设计模式中对单例模式的定义——“保证一个类仅有一个实例,并提供一个访问它的全局访问点”。很简单一句话,明确信息有两点:1、保证一个实例;2、提供全局访问点。而在多线程中保证唯一的实例就需要对懒汉模式的单例做下修改。
普通懒汉模式:
1: class Singleton{2: private Singleton(){}3: private static Singleton singleton ;4: public static Singleton getInstance(){5: if(singleton == null){6: singleton = new Singleton();7: }
8: return singleton;9: }
10: }
这种代码在单线程执行没有问题,但是在多线程中就出现了问题,如果两个线程同时调用getInstance 就new了两个实例。代码修改:
1: class Singleton{2: private Singleton(){}3: private static Singleton singleton ;4: public static Singleton getInstance(){5: if(singleton == null){6: synchronized(Singleton.class){7: if(singleton == null){8: singleton = new Singleton();9: }
10: }
11: }
12: return singleton;13: }
14: }
第7行再进行判断一遍的原因:如果两个线程同时调用getInstance,其中线程1执行,线程2阻塞,当线程1执行完毕,singleton已经实例化了;而当线程2进入,如果不做null判断那就继续创建了第二个singleton实例,故需进行双重锁定。
另外,给方法加同步锁也可以实现效果,但有人说这种方法效率太低,本人没有经过测试,暂且苟同。
1: class Singleton{2: private Singleton(){}3: private static Singleton singleton ;4: public synchronized static Singleton getInstance(){5: if(singleton == null){6: singleton = new Singleton();7: }
8: return singleton;9: }
10: }
这里关于synchronized 方法和 synchronized 块的讨论,http://www.cnblogs.com/devinzhang/archive/2011/12/14/2287675.html 这篇帖子写的很好,可以参考。