lazy_initialization
1. 最简单的thread-safe的getInstance。效率最差,每次都要检查intrinsic lock,即便是sequence的单线程调用,也耗时巨大
测试结果:在我的台式机上单线程的调用,运行999999999次需要时间11250毫秒以上,
correct but expensive
public synchronized ClassName getInstance() { if (instance == null) instance = new ClassName(); return instance; }
2. double-checked locking
volatile关键字的应用。还有cache coherence问题
// Works with acquire/release semantics for volatile // Broken under Java 1.4 and earlier semantics for volatile class Foo { private volatile Helper helper; 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... }
3. initialization-on-demand holder idiom
主要的原理是利用JVM的JLS中针对static final的处理方式达到线程安全的。
但是也有不少批评:Avoid this idiom if the construction of INSTANCE can fail. If construction of INSTANCE fails, an invocation of Something.getInstance() will result in ajava.lang.ExceptionInInitializerError error. Handling, or mishandling, of these types of construction initialization failures is a common criticism of this idiom and the singleton pattern in general.
public class Something { private Something() {} private static class LazyHolder { private static final Something INSTANCE = new Something(); } public static Something getInstance() { return LazyHolder.INSTANCE; } }
浙公网安备 33010602011771号