首先聊一下volatile关键字的作用:
1、保证内存可见性;
2、禁止指令重排序;
先说内存可见性:
1、要讲一下JMM,我们通常说的java虚拟机内存是分成主内存和线程本地内存的,这个很多文章有讲,有图。那么思考两个问题:为什么要设计线程的本地内存?这个本地内存空间究竟在哪里?
由于CPU处理速度远大于内存读写,所以CPU是带一块告诉缓存的。但是这个高速缓存非常小。通常就是几个M或者几十个M而已,每次CPU分配时间片执行线程代码时,要把指令集合还有本地方法栈加载过来,这样时间片结束前尽量不再和内存有读写交互了,时间片执行结束时,要把当前高速缓存执行的快照放回主内存,也就是我们所说的栈空间,这就解释了第一个问题。
本地内存空间是一个抽象概念,他可以认为就是本地方法栈也可以认为是高速缓存,这个看懂上边的就能理解了。
2、背景知识有了说一下可见性怎么实现的?核心两个点:
1》添加volatile的线程写操作结束时会立马更新主内存,并且会发送一个信号量告诉所有CPU对变量的引用置为失效,保证再次使用要重新到主内存加载,这一点是核心。
2》附加一点,上面提到的写操作前后会添加CAS锁,这个锁是用来保证写操作的原子性,因为写操作包含了回写CPU和发出失效指令两个动作,保证他俩的一致性。
再说禁止指令重排序:
等会更新。。。。。。