1. 为何会发生乱序
CPU为了提高效率采取的一种优化机制
当指令1去内存中读取数据并等待返回时
则wait状态的指令2可优先执行
当指令1和指令2没有依赖关系时,才会发生
2. 乱序存在的条件
不影响单线程的最终一致性
x = 1;
y = 1;
x = a;
y = b;
等不影响最终结果的可以换顺寻执行
x = 1;
x++;
则不能换顺序执行
3. 问题
乱序在多线程的情况下可能会产生难以察觉的错误
4.如何阻止乱序的发生呢
4.1 使用内存屏障组织乱序执行
内存屏障是特殊指令:这种指令之前的指令必须执行完才会执行之后的指令
4.2 JVM内存屏障
- LoadLoad屏障
- Load1,Loadload,Load2
- 确保Load1所要读入的数据能够在被Load2和后续的load指令访问前读入。
- StoreStore屏障
- Store1,StoreStore,Store2
- 确保Store1的数据在Store2以及后续Store指令操作相关数据之前对其它处理器可见
- LoadStore屏障
- Load1; LoadStore; Store2
- 确保Load1的数据在Store2和后续Store指令被刷新之前读取
- StoreLoad屏障
- Store1; StoreLoad; Load2
- 确保Store1的数据在被Load2和后续的Load指令读取之前对其他处理器可见
5. volatile的实现细节
在volatile写操作之前其他的写操作必须全部完成
在volatile写操作之后,其他的读操作才可以开始
在volatile读操作之后,其他的读操作和写操作才可以开始