线程安全性-可见性

a 夏天 提交于 2020-02-22 05:05:26

导致共享变量在线程间不可见的原因

线程交叉执行;重排序结合线程交叉执行;共享变量更新后的值没有在工作内存与主存间及时更新

JMM关于synchronized的两条规定

线程解锁前,必须把共享变量的最新值刷新到主内存;线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主存中重新读取最新的值(注意加锁和解锁是同一把锁)

可见性-volatile

通过加入 内存屏障禁止重排序优化来实现;
对volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量刷到之内存;
对volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量。

可见性-volatile读

在这里插入图片描述

可见性-volatile读

在这里插入图片描述

可见性-volatile使用

当变量作为多个线程之间的交流变量

valatile boolean inited=false;
//线程1
context=loadContext();
inited=true;

//线程2
while(!inited){
	sleep();
}
doSomethingWithConfig(context);

这段代码中,线程1的context=loadContext()和inited=true的操作不一定会按着代码逻辑顺序来的,cpu在执行时很可能重排序从而导致先执行inited=true再执context=loadContext(),这样就会导致线程2传入doSomethingWithConfig中的内容为空。为了解决这个问题使用valatile 修饰inited,禁止代码执行顺序的重排序,那么在执行inited=true之前一定会按着代码的逻辑顺序去先执行context=loadContext()。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!