并发编程三大特性-有序性

97 阅读1分钟

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的实现细节

image.png

在volatile写操作之前其他的写操作必须全部完成
在volatile写操作之后,其他的读操作才可以开始

image.png 在volatile读操作之后,其他的读操作和写操作才可以开始