指令重排原理和规则
指令重排:指的是JVM为了优化,在条件允许的情况下,对指令进行一定的重新排列,直接运行当前能够立即执行的后续指令,避开获取下一条指令所需的数据造成的等待。
线程内串行语义,不考虑多线程间的语义
不是所有的指令都能进行指令重拍:如:
写后读:a = 1;b = a;写一个变量之后,在读这个位置
写后写 :a = 1;a = 2; 写一个变量之后,再写这个变量
读后写:a = b;b = 2;读一个变量后,再写这个变量
❤ 以上语句不可重排,但是 a = 1;b = 2;是可以重排的
指令重排的基本规则:
程序顺序原则:一个线程内要保证语义的串行性
volatile规则:volatile变量的写,先发生于读
锁规则:解锁(unlock)必然发生在随后的加锁(lock)前
传递性:A 先于 B, B 先于 C,那么 A 必然先于 C
线程的 start 方法先于它的每一个动作
线程的所有操作先于线程的终结(Thread.join())
线程的中断(interrupt())先于被中断线程的代码
对象的构造函数执行结束先于finalize()方法
多线程中的有序性
在本线程内,操作都是有序的
在线程外观察,操作都是无序的,因为存在指令重排或主内存同步延时