Double-checked Locking (DCL)用来在lazy initialisation 的单例模式中避免同步开销的一个方法。
下面是这么做的一个例子。
Thread 1: ‘gets in first‘ and starts creating instance. | Thread 2: gets in just as Thread 1 has written the object reference to memory, but before it has written all thefields. |
1. Is instance null? Yes. 2. Synchronize on class. 3. Memory is allocated for instance. 4. Pointer to memory saved into instance. 7. Values for field1 and field2 are written to memory allocated for object. |
5. Is instance null? No. 6. instance is non-null, but field1 and field2 haven‘t yet been set! This thread sees invalid values for field1 and field2! |
如果解决上面的问题呢?
在类的初始化期间,JVM会去获取一个锁。这个锁可以同步多个线程对同一个类的初始化。基于这个特性,可以实现另一种线程安全的延迟初始化方案。
初始化一个类,包括执行这个类的静态初始化(static代码段)和初始化在这个类中声明的静态字段。
根据java语言规范,在首次发生下列任意一种情况时,一个类或接口类型T将被立即初始化:
- T是一个类,而且一个T类型的实例被创建;
- T是一个类,且T中声明的一个静态方法被调用;
- T中声明的一个静态字段被赋值;
- T中声明的一个静态字段被使用,而且这个字段不是一个常量字段;
- T是一个顶级类(top level class,见java语言规范的§7.6),而且一个断言语句嵌套在T内部被执行。
以前转载了Java内存模型的系列文章,理解了这些文章,上面的内容就很好理解了。
Java多线程 -- 深入理解JMM(Java内存模型) --(一)基础
Java多线程 -- 深入理解JMM(Java内存模型) --(二)重排序
Java多线程 -- 深入理解JMM(Java内存模型) --(三)顺序一致性
Java多线程 -- 深入理解JMM(Java内存模型) --(四)volatile
Java多线程 -- 正确使用Volatile变量
Java多线程 -- 深入理解JMM(Java内存模型) --(五)锁
Java多线程 -- 深入理解JMM(Java内存模型) --(六)final
Java多线程 -- 深入理解JMM(Java内存模型) --(七)总结
Java多线程 -- 单例模式的Double-checked Locking (DCL)问题
原文地址:http://blog.csdn.net/fw0124/article/details/42737171