关于volatile使用问题
来源:3-4 线程安全性-可见性
![](http://img1.sycdn.imooc.com/user/545865b90001b1d102200220-100-100.jpg)
坏淡一个
2018-05-05
还是不理解使用volatile有什么好处?就算现在没有volatile修饰,等线程1执行完成后将值写入主内存,线程2再判断为true然后执行,除了慢一点点也没什么影响啊
1回答
-
你好,有了volatile,一旦别的线程修改,这里可以得到最新的值,也能避免某些重排序。
线程1把写入主内存后,线程2如果之前已经执行了while(!inited) 判断时,那么你是无法确定线程2什么时候可以读到最新的主内存里的值的,而不是简单的慢一点点的。这里的写法也是期望在inited变成true时立刻开始执行后面的程序。
这是第一个原因,再说第二个原因,也是一个更重要的原因。如果不加volatile,线程1的两段代码可能发生重排序,就是先执行inited=true, 再执行context=loadContext(), 这样一来就会出现inited=true时,context还有短暂为空的一段时间。这时如果线程2执行时发现inited为true了,去执行doSomethingWithConfig(context)时,就会出现操作的是一个空值了,这个明显不符合预期。而线程2之前的循环判断就是为了保证loadContext()肯定执行。这时有了volatile就不一样了,他可以保证线程1先执行context=loadContext(),再执行inited=true,之后线程2才可能执行到doSomethingWithConfig(context)。保证代码执行符合预期。
我们在处理涉及到多线程共享的变量时,很多情况下需要读到变量准确的值和避免重排序,尽可能的保证当前线程的执行符合预期。这个例子还算简单,复杂一点的,有时你使用了过期的变量的值,而你以为你拿到的最新的值,就可能会导致代码的执行远离你的预期,导致程序执行出错,也可能带来很大的损失。
而为了避免这个问题,jvm里定义了volatile关键字,在需要的时候使用它,利用它的可见性及避免重排序,来尽可能保证代码按照你的预期执行。
342018-11-06
相似问题