使用关键字volatile时出现非线程安全的原因

变量在内存中工作的过程如下图所示。
使用关键字volatile时出现非线程安全的原因_第1张图片
由上,我们可以得出以下结论。

read和load阶段:从主存复制变量到当前线程工作内存;
use和assign阶段:执行代码,改变共享变量值;
store和write阶段:用工作内存数据刷新主存对应变量的值。
在多线程环境中,use和assign是多次出现的,但这一操作并不是原子性,也就是在read和load之后,如果主内存count变量发生修改之后,线程工作内存中的值由于已经加载,不会产生对应的变化,也就是私有内存和公共内存中的变量不同步,所以计算出来的结果会和预期不一样,也就出现了非线程安全问题。

对于用volatile修饰的变量,JVM虚拟机只是保证从主内存加载到线程工作内存的值是最新的,例如线程1和线程2在进行read和load的操作中,发现主内存中count的值都是5,那么都会加载这个最新的值。也就是说,volatile关键字解决的是变量读时的可见性问题 ,但无法保证原子性,对于多个线程访问同一个实例变量还是需要加锁同步。

你可能感兴趣的:(JavaSe,JVM)