双重检查锁定模式-转自维基百科
原文地址:http://zh.wikipedia.org/wiki/%E5%8F%8C%E9%87%8D%E6%A3%80%E6%9F%A5%E9%94%81%E5%AE%9A%E6%A8%A1%E5%BC%8F
双重检查锁定模式(也被称为"双重检查加锁优化","锁暗示"(Lock hint)[1]) 是一种软件设计模式用来减少并发系统中竞争和同步的开销。双重检查锁定模式首先验证锁定条件(第一次检查),只有通过锁定条件验证才真正的进行加锁逻辑并再次验证条件(第二次检查)。
该模式在某些语言在某些硬件平台的实现可能是不安全的。有的时候,这一模式被看做是反模式。
它通常用于减少加锁开销,尤其是为多线程环境中的单例模式实现“惰性初始化”。惰性初始化的意思是直到第一次访问时才初始化它的值。
考虑下面的Java代码
// Single threaded versionclass Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) { helper = new Helper(); } return helper; } // other functions and members...}
// Correct but possibly expensive multithreaded versionclass Foo { private Helper helper = null; public synchronized Helper getHelper() { if (helper == null) { helper = new Helper(); } return helper; } // other functions and members...}
// Broken multithreaded version// "Double-Checked Locking" idiomclass Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) { synchronized(this) { if (helper == null) { helper = new Helper(); } } } return helper; } // other functions and members...}
// Works with acquire/release semantics for volatile// Broken under Java 1.4 and earlier semantics for volatileclass Foo { private volatile Helper helper = null; public Helper getHelper() { Helper result = helper; if (result == null) { synchronized(this) { result = helper; if (result == null) { helper = result = new Helper(); } } } return result; } // other functions and members...}
// Correct lazy initialization in Java@ThreadSafeclass Foo { private static class HelperHolder { public static Helper helper = new Helper(); } public static Helper getHelper() { return HelperHolder.helper; }}
public class FinalWrapper<T> { public final T value; public FinalWrapper(T value) { this.value = value; }} public class Foo { private FinalWrapper<Helper> helperWrapper = null; public Helper getHelper() { FinalWrapper<Helper> wrapper = helperWrapper; if (wrapper == null) { synchronized(this) { if (helperWrapper == null) { helperWrapper = new FinalWrapper<Helper>(new Helper()); } wrapper = helperWrapper; } } return wrapper.value; }}