JAVA关键词volatile
volatile 的主要作用
- 保证变量的内存可见性
- 禁止指令重排序
什么是保证多线程下共享变量的可见性呢
当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。
这里有两种方案:
- 加锁
- 使用 volatile 关键字。
锁 synchronizer
当一个线程进入 synchronizer 代码块后,线程获取到锁,会清空本地内存,然后从主内存中拷贝共享变量的最新值到本地内存作为副本,执行代码,又将修改后的副本值刷新到主内存中,最后线程释放锁。
volatile 关键字
使用 volatile 关键字修饰共享的变量,
每个线程要操作该变量时会从主内存中将变量拷贝到本地内存作为副本,当线程操作变量副本并写回主内存后,会通过 CPU 总线嗅探机制告知其他线程该变量副本已经失效,需要从主内存中重新读取。
嗅探是实现缓存一致性的常见机制
因为volatile不具备原子性,
所以volatile 修饰的变量是线程不安全的。
要解决这个问题,我们可以使用锁机制,或者使用原子类(如 AtomicInteger)。
什么是重排序?
为了提高性能,编译器和处理器常常会在不改变数据依赖的情况下对指令做重排序
拓展:内存屏障指令