指令重排、happens-before
- volatile可以避免指令重排序,能否解释一下什么是指令重排序
JVM在编译java代码或者cpu执行JVM字节码时,对现有的指令进行重排序,主要目的是优化运行
效率(不改变程序结果的前提)
int a = 1
int b = 2
int c = 3
int d = a*b*c
定义顺序 1 ,2,3,4
计算顺序 1,3,2,4 和 2,1,3,4
虽然指令重排序可以提高执行效率,但是多线程上可能会影响结果,有什么解决办法?
解决办法:内存屏障
解释:内存屏障是屏障指令,使CPU对屏障指令之前和之后的内存操作执行结果的一种约束
- 知道 happens-before吗,能否简单解释下?
先⾏发⽣原则,volatile的内存可⻅性就提现了该原则之⼀
例⼦:
int k = 1;
int j = k;
int k = 2
分析:
假设线程A中的操作“k=1”先⾏发⽣于线程B的操作“j=k”,那确定在线程B的操作执⾏后,变量j的值
⼀定等于1,依据有两个:⼀是先⾏发⽣原则,“k=1”的结果可以被观察到;⼆是第三者线程C还没出
现,线程A操作结束之后没有其他线程会修改变量k的值。
但是考虑线程C出现了,保持线程A和线程B之间的先⾏发⽣关系,线程C出现在线程A和线程B的操作
之间,但是线程C与线程B没有先⾏发⽣关系,那j的值会是多少?答案是1和2都有可能,因为线程C
对变量k的影响可能会被线程B观察到,也可能不会,所以线程B就存在读取到不符合预期数据的⻛
险,不具备多线程安全性。
⼋⼤原则
1、程序次序规则
2、管程锁定规则
3、volatile变量规则
4、线程启动规则
5、线程中断规则
6、线程终⽌规则
7、对象终结规则
8、传递性