【JMM】java内存模型及volatile关键字底层

1.计算机的cpu模型

 。

2.

 3.JMM的模型类似于计算机CPU的模型

 我们的每一个线程都会有一个 主内存的共享变量的一个副本。

4.第一个volatile例子

不加volatile

 

 输出结果

 结果表示 标志位以及变为true。但是还是没跳出thread1的循环。

加了volatile

 

 volatile保证变量可见性。

5.JMM数据原子操作

 

6.早期多核cpu解锁可见性问题

 类似于串行化执行线程。在每个线程读数据时加锁,然后写回主内存时释放锁。

7.后期解决cpu可见性问题。

 

 这里对于各个线程在主内存里读数据并不加锁,可以并发的读。

但是当有线程向总线store 新的值时,别的线程的cpu总线嗅探机制 可以感知到数据的变化,从而使其工作内存的数据副本失效。

这时候需要重新在主内存里面读数据。

8.volatile的汇编底层

 

 这个line30就是将flag赋值为true的代码。 加了volatile后当赋值后马上回写到主内存里

9.volatile加锁解锁

 相比于总线加锁的低性能。

使用volatile+MESI可以使锁的密度降低。

在对变量进行赋值之后,马上为其变量加锁,然后向总线store。

在主内存对其更改之后,解锁。

因为当store时 其他线程开始向主内存读数据,这时候还没写入主内存呢。存在时间差。

10.

11.

12。不保证原子性的例子

 当线程1 2同时进行num++。都变成了1,但是要写入总线的时候 需要lock。

假设线程1加了lock 线程2就阻塞了。

线程1写入总线 和主内存后 线程2嗅探到num变化,于是将刚才线程2算好的1失效变为主内存中 线程1算好的1.

但是这时候线程2已经要算第2次++了,第一次++就被浪费掉。

13.有序性例子

原文地址:https://www.cnblogs.com/cckong/p/14423972.html