DCL双检查锁是的初衷是为了解决实现单例对象的懒加载时,避免过度同步导致的性能开销,在获取单例的构造方法中通过两层if null的空校验进行双层检查,在最里面的一层校验外加了synchronized同步,但是问题就是出在当构造单例实例对象时,会出现指令重排序,即实例的写入操作和实例字段的写入操作存在重排序。在外层的if null校验实例时得到不为空即对实例进行了访问。但是此时会存在访问部分构造的实例对象的问题。可以通过volatile限制对实例的指令重排序解决,但是此种方法会有一定的性能开销。另一种方法是通过静态内部类的变量延迟加载的机制实现。
参考资料:
Java内存模型FAQ(十一)新的内存模型是否修复了双重锁检查问题?
// 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; }
来源:oschina
链接:https://my.oschina.net/u/914290/blog/803185