科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道java中的双重检查模式(double-check idiom)

java中的双重检查模式(double-check idiom)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文探讨在java中使用双重检查模式(double-check idiom)的问题。

作者:袁乐天 来源:CSDN 2008年3月19日

关键字: 检查 双重 java

  • 评论
  • 分享微博
  • 分享邮件

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

private Resource resource;

public Resource getResource(){
  
if (resource == null)
    
synchronized(this)
      
if (resource==null){
        resource 
= new Resource();  
      }
   
    }
  
  }
return resource;
}


该模式是对下面的代码改进:
public synchronized Resource getResource(){
  
if (resource == null)
        resource 
= new Resource();  
  }

  
return resource;
}

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

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

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,双重检查模式就可以工作了”,参见http://gee.cs.oswego.edu/dl/cpj/updates.html。

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

private volatile Resource resource;

public Resource getResource()...{
  
if (resource == null)...
    
synchronized(this)...
      
if (resource==null)...{
        resource 
= new Resource();  
      }
   
    }
  
  }
return resource;
}

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

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章