double check为什么要加volatile,sync内代码块难道不是全部执行完才释放锁的吗? 5C

大部分帖子说的原因是在instance初始化中的3个步骤中由于指令重新排序导致线程2拿到不完整的instance,可是既然有synchronize包裹,应该是全部执行完才会释放锁的把?不应该会出现-在初始化的3步骤中,线程2突然获取到锁了啊

volatile保证了修饰的变量不能被重新排序,也就是说变量初始化的顺序固定为1、分配内存空间2、初始化一个SingletonClass对象3、将变量引用指向内存空间

这样在多线程判断时,如果对象不为null,那么指向的那个实体必定已经初始化完毕了

那么既然如此,是不是可以用atomicreference来代替volatile呢?

2个回答

早期的jvm库有bug,java5以后其实不需要,当然,用volatile比用synchronize还是要性能高一些的。

https://www.cnblogs.com/dolphin0520/p/3920373.html

ico10297024
我叫小伤 根据oyljerry的解释和我的推断,java5以后应该也需要把,double check外面那层if没有加锁,所以线程B不会等待线程A的sync代码块执行完毕,所以还是有可能得到不完整的instance?对于此推论你怎么看?
大约一年之前 回复
public class SingletonClass { 

  private static SingletonClass instance = null; 

  public static SingletonClass getInstance() { 
    if (instance == null) { 
      synchronized (SingletonClass.class) { 
        if (instance == null) { 
          instance = new SingletonClass(); 
        } 
      } 
    } 
    return instance; 
  } 

  private SingletonClass() { 

  } 

}

主要是看清检测的时机,比如当你线程A在执行 instance = new SingletonCl ass(); ** 时,它先分配了内存,然后再进行构造初始化,这里有好几步,假如刚好在分配了内存以后,还未初始化的时候,线程B来调用函数,这个时候,if (instance == null) ** 这个判断条件就为真,这样B线程就之间拿到instance 返回,然后后续使用,这个时候,就会有问题了

而volatile加入了happens-before的语义规范,被volatile修饰的写变量不能和之前的读写代码调整,读变量不能和之后的读写代码调整!因此,只要我们简单的把instance加上volatile关键字就可以了。

ico10297024
我叫小伤 话说在double check中volatile变量不能被重新排序,也可以说是volatile是为了让instance的初始化具备原子性,那么既然如此,是不是可以用atomicreference来代替volatile呢?
大约一年之前 回复
ico10297024
我叫小伤 这里你说的volatile的解释应该有问题,不是读写代码调整,而是保证了修饰的变量不能被重新排序,也就是说变量初始化的顺序固定为1、分配内存空间2、初始化一个SingletonClass对象3、将变量引用指向内存空间
大约一年之前 回复
ico10297024
我叫小伤 volatile变量规则:对一个volatile变量的写操作happen—before后面对该变量的读操作,根据说明,这个后面,应该是在单线程中适用的把?如果多线程也适用的话,一个线程读,一个线程写,难道也会按照这个规则么?感觉好像不太可能
大约一年之前 回复
ico10297024
我叫小伤 哦,我明白了。。。我之前老想着线程B在里面的if判断,所以觉得B不可能进来,没考虑到外面那个if,因为外面没有用sync块,所以不需要线程A的sync全部执行完,就可以拿到instance了;而用了volatile以后,根据happend-before规则,线程B的读操作一定会在线程A的写操作全部完成之后,是这个意思吗?那又产生了一个问题,happends-before规则是单线程中的规则把?多线程好像不适用啊
大约一年之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问