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 单例双重检查(double check)为什么不好用

JAVA 单例双重检查(double check)为什么不好用 在阅读之前,请先了解下线程并发涉及到的三个概念:原子性、可见性、有序性,可以看下这篇文章:http://www.cnblogs.co...
  • anjxue
  • anjxue
  • 2016年04月01日 17:28
  • 1329

从单例模式的Double-Check看指令重排

晚上同学问了我一个问题,单例模式的Double-Check机制在多线程模式是否会出现问题。这个问题我当时有些琢磨不透,晚上翻阅书籍记录一下这个问题的收获。  public class Singlet...
  • u012308971
  • u012308971
  • 2017年07月31日 20:20
  • 297

java 的double-check locking

《Java与模式》在讲Lazy Singleton时,提到在c++单例中广泛使用的double-checl locking,在java中确实无效的:     “在Java编译器中,LazySingl...
  • yaerfeng
  • yaerfeng
  • 2012年07月19日 12:09
  • 1733

关于java中的double check lock

实现一个正确的单例模式在熟悉的单例模式中你或许会遇到下面的方式来实现一个单例:// version 1 class Singleton { private static Singleton _...
  • scugxl
  • scugxl
  • 2017年09月07日 21:55
  • 241

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

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

java单例双重检查锁为什么需要加volatile关键字

原文地址:http://blog.csdn.net/jason0539/article/details/23297037/ 回复中的13楼 Re: 炸斯特 2015-09-04 10:49发表 [...
  • xiakepan
  • xiakepan
  • 2016年09月05日 22:49
  • 2252

分享一个java正则验证类

   网上正则验证的很多,但是没找到一个比较集中的类,这个是我工作中收集的,现在共享出来。方便大家使用,这个类可以直接运用到项目中。package com.tool.util; import j...
  • jarvis_java
  • jarvis_java
  • 2010年10月18日 16:25
  • 4425

java 校验数据是否为int、double、string类型的方法instanceof

String sContentValue = "1234567"; boolean bCheckResult = true;/* Int */try { Integer iCheckValue...
  • luliyuan
  • luliyuan
  • 2013年01月28日 13:21
  • 12154

Java并发编程:volatile关键字解析 和双重检查(Double-Check)

转载:http://www.cnblogs.com/dolphin0520/p/3920373.html http://blog.csdn.net/dl88250/article/details/5...
  • fh09102103
  • fh09102103
  • 2015年10月02日 16:55
  • 2586

Java使用double check(双重检查)实现单例模式的一个小细节

Java使用double check(双重检查)实现单例模式时,单例变量要使用volatile修饰
  • u010660307
  • u010660307
  • 2017年04月09日 20:30
  • 566
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java 中的双重检查(Double-Check)
举报原因:
原因补充:

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