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

在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中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值