Java 中的双重检查(Double-Check)

原创 2010年03月31日 22:03:00

在 Effecitve Java 一书的第 48 条中提到了双重检查模式,并指出这种模式在 Java 中通常并不适用。该模式的结构如下所示:

 

 

该模式是对下面的代码改进:

 

这段代码的目的是对 resource 延迟初始化。但是每次访问的时候都需要同步。为了减少同步的开销,于是有了双重检查模式。

在 Java 中双重检查模式无效的原因是在不同步的情况下引用类型不是线程安全的。对于除了 long 和 double 的基本类型,双重检查模式是适用 的。比如下面这段代码就是正确的:

 

上面就是关于java中双重检查模式(double-check idiom)的一般结论。但是事情还没有结束,因为java的内存模式也在改进中。Doug Lea 在他的文章中写道:“根据最新的 JSR133 的 Java 内存模型,如果将引用类型声明为 volatile,双重检查模式就可以工作了”,参见 http://gee.cs.oswego.edu/dl/cpj/updates.html

所以以后要在 Java 中使用双重检查模式,可以使用下面的代码:

 

 

当然了,得是在遵循 JSR133 规范的 Java 中。

所以,double-check 在 J2SE 1.4 或早期版本在多线程或者 JVM 调优时由于 out-of-order writes,是不可用的。 这个问题在 J2SE 5.0 中已经被修复,可以使用 volatile 关键字来保证多线程下的单例。

 

推荐方法 是Initialization on Demand Holder(IODH),

详见 http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom

 

版权声明:欢迎加入开源技术 Q 群:242561391,让学习和分享成为一种习惯!

相关文章推荐

Java之美[从菜鸟到高手演练]之atomic包的原理及分析

作者:二青个人站点:zhangerqing.cn    邮箱:xtfggef@gmail.com    微博:http://weibo.com/xtfggefAtomic简介Atomic包是java....

Java多线程调度—优先级

一. 线程的调度-优先级 与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行(优先级低的也可能会被执行)。线程的优先级用...

Java单例模式中双重检查锁的问题

单例创建模式是一个通用的编程习语。和多线程一起使用时,必需使用某种类型的同步。在努力创建更有效的代码时,Java 程序员们创建了双重检查锁定习语,将其和单例创建模式一起使用,从而限制同步代码量。然而,...

探析Spring AOP(二):Spring AOP的实现机制

Spring AOP 属于第二代 AOP, 采用动态代理机制和字节码生成技术实现 。   与最初的 AspectJ 采用编译器将横切逻辑织入目标对象不同,动态代理机制和字节码生成都是在运行期间为目标...

java 双重检查锁定及单例模式

双重检查锁定及单例模式全面理解这一失效的编程习语Peter Haggar , 高级软件工程师, IBMPeter Haggar 是 IBM 在北卡罗来纳州的 Research Triangle Pa...

【转】Java异常处理的六个恶习

声明:由于无法找到原创作者,故没有贴出原文的链接地址。但觉得这篇文章写得挺不错,还是把它转载了。如有冒犯到原作者的地方,还请原谅。最后谢谢原作者的精彩文章。你觉得自己是一个Java专家吗?是否肯定自己...

Java并发编程:Java内存模型和volatile关键字解析

Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)