操作系统如何保证一致性、有序性、原子性(Unsafe类以下)

首先放总结图:

操作系统如何保证一致性、有序性、原子性(Unsafe类以下)_第1张图片

一、问题引入:

Java中广泛使用的CAS技术底层源码都是使用的Unsafe类,而这是一个native方法,本质上绕过了JVM,是由C/C++语言编写的,直接与操作系统底层相关,所以可以实现操作的原子性。

那么操作系统底层是如何保证操作的数据一致性、有序性、原子性的呢?

  • 一致性:总线窥探原理 + 缓存一致性协议(硬件层面)
  • 有序性:解决指令重排问题,内存屏障(软件层面,使用barrier编译器告诉计算机要按照顺序执行这段指令)
  • 原子性:缓存一致性协议

二、cpu处理数据的过程:

每个CPU都和主线连接,每个缓存、内存之间的相互通信都要经过总线进行。一般CPU执行指令的顺序如下:

1. CPU从磁盘读取程序指令和数据到内存(拿到数据存储的地址的指针) 
2. 加载指令和数据到CPU的缓存
3. CPU执行指令,将结果写入缓存 
4. 将缓存中的结果数据写回内存

三、如何保证一致性和原子性:

不同CPU连接的内存可以保存同一个变量,不加限制的话就会存在并发问题,所以当某个CPU要改变某个共享数据时,会先通过总线告知其他CPU不可使用该数据,收到其他CPU的确认信号后,这个CPU再开始对这个数据的修改.(MESI协议)

注:此处会有指令重排问题:

等待其他CPU的ACK信号会耗时,所以这里会有指令重排的问题,也就是CPU优化了指令的执行顺序,要修改共享数据时,不会阻塞等待其他CPU的响应,而是先往下执行对非共享数据操作的指令,收到其他CPU的ACK信号以后再反过来执行之前的指令。

所以以上指令重排优化过程会导致以下的指令执行顺序性问题,并发情况下会出现数据计算结果异常。

四、如何保证指令执行顺序性:

使用barrier编译器(内存屏障,软件层面防止指令重排)编译指令,计算机底层会取消指令重排优化,强制按照程序员规定的顺序执行指令。

你可能感兴趣的:(JAVA学习进阶,java,操作系统)