设计模式学过差不多也有一年了  可到现在只记得零星的几个 看来是有必要复习一遍了。
有些大的对象其实我们只需要一个,比如说:线程池、缓存、日志对,充当打印机、显卡等设备的驱动程序的对象等,这类对象只能有一个实例,如果制造出多个就会产生许多问题。
单件模式确保一个类只能有一个实例,并且提供一个全局的访问点。
public class Singleton {
    private static Singleton instance = null;
    
    private Singleton () { }
    
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        
        return instance;
    }
}
初看起来这段代码没有一点问题,但如果发生多线程的情况呢?因为多线程的不确定性,就很有可能产生很多个Singleton实例了。再来改善下让它能够适应多线程,如下:
public class Singleton {
    private static Singleton instance = null;
    
    private Singleton () {}
    
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        
        return instance;
    }
}
这样做多线程的问题是消除了,但却产生另外的问题:以后每次访问都需要执行同步方法,产生了严重的性能问题。再来改善下多线程,如下:
1、使用急切创建实例,而不使用延迟加载
public class Singleton {
    private static Singleton instance = new Singleton();
    
    private Singleton () {}
    
    public static  Singleton getInstance() {
        return instance;
    }
}
现在我们依赖JVM在加载这个类时马上创建此类的单件实例,JVM保证在任何线程访问instance静态变量之前先创建此实例。
2、使用双重检查加锁,在getInstance中减少使用同步
public class Singleton {
    // volatile 有效的确保当instance被初始化成实例时,多线程正确的处理instance变量。
    private volatile static  Singleton instance = null;
    
    private Singleton () {}
    
    public static  Singleton getInstance() {
        
        // 如果实例不存在就进入实例块,只有第一次才彻底执行这里的代码。
        if (instance == null) {
            // 这里有效的阻止了多线程问题的产生
            synchronized (Singleton.class) {
                // 进入区块后,再检查一次,只有实例为空才创建实例。
                if (instance == null) {
                    instance= new Singleton();
                }
            }
        }
        
        return instance;
    }
}