gpt4 book ai didi

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

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 29 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Java中的双重检查(Double-Check)详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

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

?
1
2
3
4
5
6
7
8
9
10
public Resource getResource() {
  if (resource == null ) { 
   synchronized ( this ){ 
    if (resource== null ) {
     resource = new Resource(); 
    }  
  
  }
  return resource;
}

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

?
1
2
3
4
5
6
public synchronized Resource getResource(){
  if (resource == null ){ 
     resource = new Resource(); 
  }
  return resource;
}

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

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

?
1
2
3
4
5
6
7
8
9
10
11
private int count;
public int getCount(){
  if (count == 0 ){ 
   synchronized ( this ){ 
    if (count == 0 ){
     count = computeCount(); //一个耗时的计算
    }  
  
  }
  return count;
}

 上面就是关于java中双重检查模式(double-check idiom)的一般结论。但是事情还没有结束,因为java的内存模式也在改进中。Doug Lea 在他的文章中写道:“根据最新的 JSR133 的 Java 内存模型,如果将引用类型声明为 volatile,双重检查模式就可以工作了”。所以以后要在 Java 中使用双重检查模式,可以使用下面的代码:

?
1
2
3
4
5
6
7
8
9
10
11
private volatile Resource resource;
public Resource getResource(){
  if (resource == null ){ 
   synchronized ( this ){ 
    if (resource== null ){
     resource = new Resource(); 
    }  
  
  }
  return resource;
}

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Singleton {
   private volatile Singleton instance = null ;
   public Singleton getInstance() {
     if (instance == null ) {
       synchronized ( this ) {
         if (instance == null ) {
           instance = new Singleton();
         }
       }
     }
     return instance;
   }
}

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

?
1
2
3
4
5
6
7
8
9
public class Singleton {
   static class SingletonHolder {
     static Singleton instance = new Singleton();
   }
   
   public static Singleton getInstance(){
     return SingletonHolder.instance;
   }
}

以上就是本文的全部内容,希望对大家学习java程序设计有所帮助.

最后此篇关于Java中的双重检查(Double-Check)详解的文章就讲到这里了,如果你想了解更多关于Java中的双重检查(Double-Check)详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com