设计模式之单例模式——Singleton

时间:2022-06-24 19:51:40

                    设计模式之单例模式——Singleton

设计意图:

保证类仅有一个实例,并且可以供应用程序全局使用。为了保证这一点,就需要这个类自己创建自己的对象,并且对外有公开的调用方法。而且,别的类不能实例化它,所以构造方法要设置为私有的。

单例模式的要点   

一是某个类只能有一个实例;

二是它必须自行创建这个实例;

三是它必须自行向整个系统提供这个实例。

例如:

有一个"单例对象",而"客户甲"、"客户乙" 和"客户丙"是单例对象的三个客户对象。可以看到,所有的客户对象共享一个单例对象。而且从单例对象到自身的连接线可以看出,单例对象持有对自己的引用。一些资源管理器常常设计成单例模式。在计算机系统中,需要管理的资源包括软件外部资源,譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler, 以避免两个打印作业同时输出到打印机中。每台计算机可以有若干传真卡,但是只应该有一个软件负责管理传真卡,以避免出现两份传真作业同时传到传真卡中的情况。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。

设计模式之单例模式——Singleton

实现的方法:

单例模式有很多种,下面就来介绍一下单例模式的几种使用方法吧:
【饿汉模式】饿汉法就是在第一次引用该类的时候就创建对象实例,而不管实际是否需要创建。

public   class   Singleton{
private static final Singleton singleton = new Singleton();
/**
* 私有构造函数
*/
private Singleton(){ }
/**
* 获得实例
* @return
*/
public static Singleton getInstance(){
return singleton;
}
public static void say(){
System.out.println("单例模式创建啦!"); }
}
public class main {
public static void main(String[] args) {
main m=new main();
Singleton.getInstance().say();
} }

这样做的好处是编写简单,但是无法做到延迟创建对象。但是我们很多时候都希望对象可以尽可能地延迟加载,从而减小负载,所以就需要下面的懒汉法:

【懒汉法】

这种方法可以实现延时加载,但是有一个致命弱点:线程不安全。如果有两条线程同时调用getSingleton()方法,就有很大可能导致重复创建对象。

public class Singleton {
private static Singleton singleton = null;
private Singleton(){}
public static Singleton getSingleton() {
if(singleton == null) singleton = new Singleton();
return singleton;
}
}

解决线程不安全的三种方法:

1、在getInstance方法上加同步

public static synchronized Singleton getInstance() {
if (single == null) {
single = new Singleton();
}
return single;
}
 

2、双重检查锁定

synchronized (Singleton.class),相当于在Singleton对象上加了锁,任何一个线程如果的到了这把锁就可以先运行,直到到他执行完其他线程才有可能得到这把锁,再进入执行。
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}

3、静态内部类

public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}

思考:java中单例模式和静态类(一个类,所有方法为静态方法)的区别

由于单例模式和静态类都具有良好的访问性,它们之间有许多相似之处,例如,两者可以直接使用而无须创建对象,都可提交唯一实例,在一个非常高的高度上看起来它们都为是用于同样的任务。

1.那么在java中什么时候该使用单例模式,什么时候该使用静态类呢?

       如果你的单例不需要维护任何状态,仅仅提供全局访问的方法,这种情况考虑使用静态类,静态方法比单例更快,因为静态的绑定是在编译期就进行的。但是要记住,不建议在静态类中维护状态信息,特别是在并发环境中,若无适当的同步措施而修改多线程并发时,会导致坏的竞态条件。
      如果你需要将一些工具方法集中在一起时,你可以选择使用静态方法,但是别的东西,要求单例访问资源时,应该使用单例模式。
 
2.Java中单例(变现类)与静态类(表现方法)的区别
1)静态类比单例具有更好的性能,因为静态方法在编译期绑定。
2)再次,它们的区别是override的能力,因Java中的静态方法是不可以覆盖的,这就导致其木有太多的灵活性,另一面,你可通过继承的方式覆盖单例类中定义的方法。
3)静态类很难模拟,因此难于单例测试,单例更容易模拟,因为也比静态类易于编写单元测试,不论神马单例期望神马,你都可以传递模拟对象,例如构造方法或方法参数。
4)如果你的需求中需要维护状态信息,则单例比静态类更适合,因为后者在维护状态信息方面是非常可怕的,并导致狡滑的bug。
5)如果是一个非常重的对象,单例可以懒加载,但是静态类没有这样的优势,并且非常热切的加载。
6)许多依赖注入的框架对单例都有良好的管理,例如Spring,使用它们非常容易。
 
 
3.Java中,选择单例而不是静态类的优点
单例与静态主要的优点是前者比后者更具有面向对象的能力,使用单例,可以通过继承和多态扩展基类,实现接口和更有能力提供不同的实现,如果我们讨论java.lang.Runtime,在Java中它是单例,调用getRuntime()方法,会基于不同的JVM返回不同的实现,但也保证了每个JVM中实有一个实例,如果java.lang.Runtime是一个静态类,不太可能因不同的JVM返回不同的实现。
 
这就是Java中单例与静态类的区别,当你需要一个全能力的对象时,选择单例,如果仅仅是将一些静态方法预售,使用静态类。

设计模式之单例模式——Singleton的更多相关文章

  1. 设计模式(4) -- 单例模式(Singleton)

    设计模式(4)  -- 单例模式(Singleton) 试想一个读取配置文件的需求,创建完读取类后通过New一个类的实例来读取配置文件的内容,在系统运行期间,系统中会存在很多个该类的实例对象,也就是说 ...

  2. 乐在其中设计模式(C#) - 单例模式(Singleton Pattern)

    原文:乐在其中设计模式(C#) - 单例模式(Singleton Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 单例模式(Singleton Pattern) 作者:weba ...

  3. 【设计模式】单例模式-Singleton

    [设计模式]单例模式-SingletonEnsure a class has only one instance, and provide a global point to access of it ...

  4. 设计模式之——单例模式(Singleton)的常见应用场景

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  5. 设计模式之单例模式(Singleton Pattern)

    单例模式 单例模式(Singleton Pattern)在java中算是最常用的设计模式之一,主要用于控制控制类实例的数量,防止外部实例化或者修改.单例模式在某些场景下可以提高系统运行效率.实现中的主 ...

  6. 设计模式一: 单例模式(Singleton)

    简介 单例模式是属于创建型模式的一种(另外两种分别是结构型模式,行为型模式).是设计模式中最为简单的一种. 英文单词Singleton的数学含义是"有且仅有一个元素的集合". 从实 ...

  7. 设计模式之——单例模式(Singleton)的常见应用场景(转):

    单例模式(Singleton)也叫单态模式,是设计模式中最为简单的一种模式,甚至有些模式大师都不称其为模式,称其为一种实现技巧,因为设计模式讲究对象之间的关系的抽象,而单例模式只有自己一个对象,也因此 ...

  8. java设计模式之 单例模式 Singleton

    static 的应用 单例模式 Singleton 单例:保证一个类在系统中最多只创建一个实例. 好处:由于过多创建对象实例,会产生过多的系统垃圾,需要GC频繁回收,由于GC会占用较大的系统资源,所有 ...

  9. 【设计模式】单例模式 Singleton Pattern

    通常我们在写程序的时候会碰到一个类只允许在整个系统中只存在一个实例(Instance)  的情况, 比如说我们想做一计数器,统计某些接口调用的次数,通常我们的数据库连接也是只期望有一个实例.Windo ...

随机推荐

  1. Hexo的Next主题配置

    使用Next主题 在这里Downloads Next主题代码 将下载的代码放在myBlog/next目录下 设置站点myBlog/_config.yml的theme字段值为next 生成新页面hexo ...

  2. Application对象、Session对象、Cookie对象、Server对象初步认识

    Application对象:记录应用程序参数的对象 用于共享应用程序级信息,即多个用户共享一个Application对象.在第一个用户请求ASP.NET文件时,将启动应用程序并创建Applicatio ...

  3. jQueryUI日期显示

    <script type="text/javascript" src="js/My97DatePicker/WdatePicker.js">< ...

  4. Onmouseover被调用多次

    当一个容器,如div,不包含元素时.Onmouseover只执行一次,正常.当这个div包含其他子元素的时候,这个事件就被执行了多次,今天遇到了这个问题,特此记录下,解决方案. 这个是由于onmous ...

  5. IO流的练习2 —— 复制单级文件夹中的文件

    需求:把C:\Users\Administrator\Desktop\记录\测试里面的所有文件复制到 C:\Users\Administrator\Desktop\新建文件夹\copy文件夹中 分析: ...

  6. python两个dataframe的合并

    见http://pandas.pydata.org/pandas-docs/stable/merging.html

  7. HTTP全部报文首部字段

    总结了一下HTTP各种报文首部字段. HTTP报文类型与结构 HTTP报文结构 报文首部 空行(CR+LF) 报文主体 HTTP报文类型 http有两种类型报文,请求报文和响应报文两种报文的首部结构如 ...

  8. Java多线程之 ThreadLocal

    一.什么是ThreadLocal? 顾名思义它是local variable(线程局部变量).它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可以独立地改变自己的副 ...

  9. &num;JAVA操作LDAP

    package com.wisdombud.unicom.monitor.ldap; import java.util.ArrayList; import org.slf4j.Logger; impo ...

  10. WordPress 使用 Pie-Register 添加前台注册、登录、找回密码和编辑个人资料功能

    转自:http://www.wpdaxue.com/front-end-publishing.html Pie-Register 是一个功能比较完善的 WordPress 才能,使用它可以很方便添加和 ...