【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.有序性例子

 

posted @ 2021-02-21 00:32  枫叶像思念  阅读(54)  评论(0编辑  收藏  举报