double-check

在Effective Java一书中提到double-check模式,并指出该模式在java中通常并不适用。该模式的结构如下

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

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

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

 为什么要有这个改进呢?首先第二段代码是对resource延迟初始化,等到第一次调用getResource()方法时才初始化。但是以后每次调用此方法都需要同步,而其实这个对象只会初始化一次。于是有了上面的改进

在java中double-check模式无效的原因是不同步情况下引用类型不是线程安全的。不过对于除了long和double的基本类型,double-check模式是使用的。

但是java的内存模式是不断改进的。Doug Lea在它的文章中写道“根据最新的JSR133的java内存模型,如果将引用类型声明为volatile,double-check模式就可以工作了”

如下

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

想起写过的一段代码异曲同工,有一个synchronized void start()方法,内部逻辑只走一次。有一个isStarted变量用于判断start()逻辑是否走过,代码如下

if(!isStarted){
  synchronized void  start(){
     if(!isStarted){
          逻辑实现
          isStarted = true;
      }
    }
};

转自:http://blog.csdn.net/dl88250/article/details/5439024

猜你喜欢

转载自xiaoxiaoher.iteye.com/blog/2372324