首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化。
但是Effective Java书中说过:除非绝对必要,否则就不要这么做。
1. DCL (double checked locking)双重检查:
如果出于性能的考虑而需要对实例域(注意这个属性并没有被static修饰)使用延迟初始化,就使用双重检查模式
public class Singleton {private volatile Singleton uniqueInstance;private Singleton(){}public static Singleton getInstance(){if(uniqueInstance == null){ //#1synchronized(Singleton.class){ //#2if(uniqueInstance == null){ //#3uniqueInstance = new Singleton(); //#4System.out.println(Thread.currentThread().getName() + ": uniqueInstance is initalized..."); //#5.1} else {System.out.println(Thread.currentThread().getName() + ": uniqueInstance is not null now..."); //#5.2 }}}return uniqueInstance;} }
2. lazy initialization holder class(静态内部类):
如果出于性能的考虑而需要对静态域(注意这个属性被static修饰)使用延迟初始化,就使用lazy initialization holder class模式。
1 public class Singleton { 2 3 private static class SingletonHolder { 4 /** 5 * 静态初始化器,由JVM来保证线程安全 6 */ 7 private static Singleton instance = new Singleton(); 8 } 9 10 private Singleton(){ 11 } 12 13 public static Singleton getInstance(){ 14 return SingletonHolder.instance; 15 } 16 }
最后,以上两种方法都不是实现单例模式的最好方式,最好的是枚举模式,coming soon...