2

一、为什么需要单例模式?
可以保证一个类仅有一个实例,控制实例数目,节约系统的资源。比如:数据库的连接池。一些资源管理器常被设计成单例模式

二、怎么使用

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.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.3、双检锁/双重检验锁(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.4、枚举
是否多线程安全:
是否 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-...


心无私天地宽
513 声望22 粉丝