关于单例模式

1、为何须要单例模式?
能够保证一个类仅有一个实例,控制实例数目,节约系统的资源。好比:数据库的链接池。一些资源管理器常被设计成单例模式html

2、怎么使用java

2.1 饿汉式
是否多线程安全:
是否 Lazy 初始化:
描述:
优势:没有加锁,执行效率提升
缺点:在某些状况下,不是由于调用getInstance而致使的类初始化的话,那么会存在浪费内存的状况
该模式是基于classLoader机制避免多线程的问题,当读取类的静态字段(类静态常量不是)、调用类的静态方法时(固然还有不少状况会触发类的初始化,更多细节参考深刻理解JVM虚拟机)。会触发类的初始化。当进行初始化时,JVM会为类的静态语句块和为类变量赋值操做,生成<clinit>的汇编指令,该指令保证只有一个线程运行。会阻塞其余线程,所以能保证只初始化一次。
备注:有人说在类加载时就会初始化,浪费内存,我的感受是不对的。首先JVM的类加载会进行类的加载(加载class文件),验证(验证字节码文件),准备(为类变量分配内存并赋初值),解析(将符号引号转为直接引用);紧接着再初始化,可是须要注意的是,已经说明JVM何时才会为类进行初始化。因此,说类在加载时就会初始化,我的感受是不对的。若是我的讲述错误,请留言数据库

代码示例:编程

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
}

2.二、静态内部类
是否多线程安全:
是否 Lazy 初始化:安全

代码示例:多线程

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

2.三、双检锁/双重检验锁(DCL,double checked locking)
是否多线程安全:
是否 Lazy 初始化:
描述:
缺点:实现复杂,且效率太低,每次都须要判断一次if。不推荐使用
请注意
若是singleton变量没有加上volatile,那么就是非线程安全的。来模拟一下:
线程A走到④处,初始化完毕了singleton,线程B走到②处。由于没有加volatile,因此此时singleton可能不会对其余内存当即可见,因此线程B也走到了④,所以,实例化了2个对象。
代码示例:并发

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {              ①
        synchronized (Singleton.class) {  ②
        if (singleton == null) {          ③
            singleton = new Singleton();  ④
        }  
        }  
    }  
    return singleton;  
    }  
}

2.四、枚举
是否多线程安全:
是否 Lazy 初始化:
描述:推荐使用
对于枚举类来讲,每一个对象(INSTANCE)都是被public static final修饰的。其次构造函数默认私有。因此用来实现单例模式,是很是适合的。
在Effective Java第二版的第77条,推荐使用枚举实现单例模式。
代码示例:函数

public enum Test{  
    INSTANCE;  
    private Singleton singleton;
    Test() {
        singleton = new Singleton;
    }
    public Singleton getInstance() {
        return singleton;
    }
}

有关参考:
java并发编程实战
EffectiveJava 第二版
http://www.runoob.com/design-...线程

相关文章
相关标签/搜索