volatile实现原理
volatile可以保证线程可见性且提供了一定的有序性,但是无法保证原子性,即 volatile 保证了 可见性和有序性 没有原子性 。在JVM底层volatile是采用“内存屏障”来实现的。
- 问题的提出 计算机在运行程序时,每条指令都是在CPU中执行的,在执行过程中势必会涉及到数据的读写。我们知道程序运行的数据是存储在主存中,这时就会有一个问题,读写主存中的数据没有CPU中执行指令的速度快,如果任何的交互都需要与主存打交道则会大大影响效率,所以就有了CPU高速缓存。CPU高速缓存为某个CPU独有,只与在该CPU运行的线程有关。
有了CPU高速缓存虽然解决了效率问题,但是它会带来一个新的问题:数据一致性。在程序运行中,会将运行所需要的数据复制一份到CPU高速缓存中,在进行运算时CPU不再也主存打交道,而是直接从高速缓存中读写数据,只有当运行结束后才会将数据刷新到主存中。举一个简单的例子:
i++i++
当线程运行这段代码时,
首先会从主存中读取i( i = 1),
然后复制一份到CPU高速缓存中,
然后CPU执行 + 1 (2)的操作,
然后将数据(2)写入到告诉缓存中,
最后刷新到主存中。
其实这样做在单线程中是没有问题的,有问题的是在多线程中。如下:
假如有两个线程A、B都执行这个操作(i++),按照我们正常的逻辑思维主存中的i值应该