Java并发编程实战--双重检查加锁( double check lock)与延迟初始化占位
来源:互联网 发布:河南科技大学网络认证 编辑:程序博客网 时间:2024/05/17 12:53
DCL
在任何一本介绍并发的书中都会讨论声名狼藉的双重检查加锁(DCL)。
下图来自:http://zoroeye.iteye.com/blog/2058889
DCL的真正问题在于:当在没有同步的情况下读取一个共享对象时,可能发生的最糟糕的事情只是看到一个失效值(在这种情况下是一个空值),此时DCL方法将通过在持有锁的情况下在此尝试来避免这种风险。然而,实际情况远比这种情况糟糕——线程可能看到引用的当前值,但对象的状态值却是失效的,这意味着线程可以看到对象处于无效或错误的状态。
在JVM的后续版本(Java5.0以及更高的版本)中,如果把resource声明为volatile类型,那么就能修正这个问题。
public class DoubleCheckedLocking { //对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入。 private volatile static Resource resource; public static Resource getInstance() { if (resource == null) { synchronized (DoubleCheckedLocking.class) { if (resource == null) resource = new Resource(); } } return resource; } static class Resource { }}
缺乏同步会导致无法实现可见性,这使得确定何时写入对象引用而不是原语值变得更加困难。在缺乏同步的情况下,可能会遇到某个对象引用的更新值(由另一个线程写入)和该对象状态的旧值同时存在。(这就是造成著名的双重检查锁定(double-checked-locking)问题的根源,其中对象引用在没有同步的情况下进行读操作,产生的问题是您可能会看到一个更新的引用,但是仍然会通过该引用看到不完全构造的对象)。
DCL方法已经被广泛地废弃了,延迟初始化占位类模式能带来同样的优势,并且更容易理解。
延迟初始化占位
使用一个专门的类来初始化Resource。JVM将推迟ResourceHolder的初始化操作,直到开始使用这个类时才初始化,并且由于通过一个静态初始化来初始化Resource,因此不需要额外的同步。当任何一个线程第一次调用getResouce时,都会使ResouceHolder被加载和被初始化,此时静态初始化器将执行Resource的初始化操作。
public class ResourceFactory { private static class ResourceHolder { public static Resource resource = new Resource(); } public static Resource getResource() { return ResourceHolder.resource ; }}
Java并发编程实战pdf及案例源码下载:
http://download.csdn.net/detail/xunzaosiyecao/9851028
作者:jiankunking 出处:http://blog.csdn.net/jiankunking
- Java并发编程实战--双重检查加锁( double check lock)与延迟初始化占位
- 并发编程的艺术-双重检查锁定与延迟初始化
- Java多线程并发中的双重检查锁定与延迟初始化
- 延迟初始化,双重检查加锁的陷阱
- Java并发编程:volatile关键字解析 和双重检查(Double-Check)
- 【Java】双重检查锁定(Double-checked locking)与延迟初始化(Initialization on demand holder)
- 《Java并发编程的艺术》第三章·附一——双重检查锁定与延迟初始化
- Java 中的双重检查(Double-Check)
- Java 中的双重检查(Double-Check)
- Java 中的双重检查(Double-Check)
- Java 中的双重检查(Double-Check)
- Java 中的双重检查(Double-Check)
- 双重检查锁定与延迟初始化
- 双重检查锁定与延迟初始化
- 双重检查锁定与延迟初始化
- 双重检查锁定与延迟初始化
- 双重检查锁定与延迟初始化
- 双重检查锁定与延迟初始化
- eclipse的版本
- Android 使用SQL数据库
- Cocos2d-x使用CCGLProgram和Shader文件实现精灵置灰
- 马上大学毕业了,为什么我找不到工作?
- 系统分析与设计学习笔记(二)用例模型
- Java并发编程实战--双重检查加锁( double check lock)与延迟初始化占位
- 设计模式-单例(Singleton)模式
- Win7系统设置家庭组提示此计算机无法连接到家庭组的解决方法图文教程
- Git fetch和git pull的区别
- 第一次使用Android Studio时你应该知道的一切配置
- thinkphp5 配置在sae,axios请求出现500的解决方法!
- socket编程以及select、epoll、poll示例详解
- Java使用Kafka初探
- 101. Symmetric Tree