预备知识
原子操作
简单来说,原子操作(atomic)就是不可分割的操作,在计算机中,就是指不会因为新城调度被打断的操作。
比如,简单的赋值就是一个原子操作:
m = 6 //这是个原子操作
假如m原先的值为0,那么对于这个操作,要么执行成功m编程了6,要么没执行m还是0,而不会出现诸如m=3,这种中间状态。
但是声明并赋值就不是一个原子操作:
int n = 6; //这个不是一个原子操作
对于这个语句至少会有来个操作:
①声明一个变量n
②给n赋值为6
这样就会有一个中间状态:变量n已经被声明了但是还没有被赋值的状态。在多线程中,由于线程执行顺序的不确定性,如果两个线程都使用m,就可能会导致不稳定的结果出现。
指令重排
简单来说,就是计算机为了提高执行效率,会做的一些优化,在不影响最终结果的情况下,可能会对一些语句的执行顺序进行调整。
比如,这一段代码:
int a ; // 语句1 a = 8 ; // 语句2 int b = 9 ; // 语句3 int c = a + b ; // 语句4
正常来说,对于顺序结构,执行的顺序是自上到下,也即1234。但是,由于指令重排的原因,因为不影响最终的结果,所以,实际执行的顺序可能会变成3124或者1324。由于语句3和4没有原子性的问题,语句3和语句4也可能会拆分成原子操作,再重排。——也就是说,对于非原子性的操作,在不影响最终结果的情况下,其拆分成的原子操作可能会被重新排列执行顺序。