DCL双检查锁是的初衷是为了解决实现单例对象的懒加载时,避免过分同步致使的性能开销,在获取单例的构造方法中经过两层if null的空校验进行双层检查,在最里面的一层校验外加了synchronized同步,可是问题就是出在当构造单例实例对象时,会出现指令重排序,即实例的写入操做和实例字段的写入操做存在重排序。在外层的if null校验实例时获得不为空即对实例进行了访问。可是此时会存在访问部分构造的实例对象的问题。能够经过volatile限制对实例的指令重排序解决,可是此种方法会有必定的性能开销。另外一种方法是经过静态内部类的变量延迟加载的机制实现。java
参考资料:性能
Java内存模型FAQ(十一)新的内存模型是否修复了双重锁检查问题?this
// double-checked-locking - don't do this! private static Something instance = null; public Something getInstance() { if (instance == null) { synchronized (this) { if (instance == null) instance = new Something(); } } return instance; }
private static class LazySomethingHolder { public static Something something = new Something(); } public static Something getInstance() { return LazySomethingHolder.something; }