单例模式的双检加锁机制
1 public class Singleton {
2 private volatile static Singleton instance;
3
4 private Singleton() {
5 }
6
7 public static Singleton getInstance() {
8 if (instance == null) {
9 synchronized (Singleton.class) {
10 if (instance == null) {
11 instance = new Singleton();
12 }
13 }
14 }
15
16 return instance;
17 }
18 }
加入了双重判断:
本来只要加锁中的判断,但是为了提高并发性,加了外层的判断,(当两个线程同时进行时,第二个线程就可以在第一个判断中绕过加锁阶段)。但是如果仅仅这样,就会产生主存与寄存器的信息不同步的问题,即两个线程中后执行的线程在前线程初始化完毕,但信息还在寄存器的时候,就会依旧判断为null,进而产生重复创建的问题,所以必须对返回值的变量进行volatile的修饰,以保证新的值对其它线程可见。
补充:第9行可以锁住任何一个对象,要进入临界区必须获得这个对象的锁。由于并不知道其它对象的锁的用途,所以这里最好的方式是对 Singleton.class 进行加锁。