小组Java

上述代码是使用”synchronized双重锁机制”的单例模式,我一直有疑问为何要加volatile关键字?

目前得到的答案如同注释所写,是利用了volatile关键字的防止指令重排序功能,保证非原子操作的禁止重排序。

我的问题:

1.那么如何验证不加volatile抛出异常的场景(目前我的测试都是正常的!)?

2.synchronize不是也具有防止指令重排序的功能,加volatile关键字是不是多余?

1 1 收藏


直接登录
最新评论
  • HiUranus Hacker 01/22

    问题2,Happen-before仅仅当另一个线程获得了锁之后才成立,所以 synchronized block 里面的 if test 永远不会读到未同步好的中间值。但在当前线程synchronized初始化块退出之后,另一个线程获得锁之前,第一个在synchronized外面的if test就有可能读到未同步好的值。所以volatile还是必需的。

     

    问题1,这个测试比较难做,还要看看生成的Byte code到底是什么顺序。但你的测试代码首先不对,这种错误仅可能发生在一个线程synchronized退出后另一个进入之前,而一旦instance不为null后,synchronized block就再也不会进入了,所以你测试getInstance一亿次也没用