定义
一旦一个共享变量(类的成员变量,类的静态成员变量)被 volatile 修饰之后:
1.保证了不同线程对这个变量进行操作的可见性,即一个线程修改了某个变量的值,这个新值对其他线程来说是立即可见的。
2.禁止指令重排序
3.volatile 不能保证对变量操作的原子性
实现原理
volatile关键字在底层的实现主要是通过内存屏障来实现。内存屏障是一种CPU指令,用于强制执行CPU的内部缓存与主存之间的数据同步。
在Java中,当线程读取一个 volatile 变量时,会从主内存中读取变量的新值,并把它存储到线程的工作内存。当线程写入一个 volatile 变量时,会把变量的值写入到线程的工作内存,并强制将这个值刷新到主内存中。这样就保证了 volatile 变量的可见性和有序性
内存屏障
内存屏障是一种硬件机制,用于控制CPU缓存和主内存之间的数据同步。在Java中,内存屏障通常有两种:读屏障和写屏障。
在有内存屏障的地方,会禁止指令重排序,即屏障下面的代码不能跟屏障上面的代码交换执行顺序。在有内存屏障的地方,线程修改完共享变量以后会马上把该变量从本地内存写回到主内存,并且让其他线程本地内存中该变量副本失效(使用MESI协议)
MESI协议是一种缓存一致性协议,它是支持写回缓存的最常用协议。MESI协议基于总线嗅探机制实现了事务串形化,也用状态机机制降低了总线带宽压力,做到了CPU缓存一致性。MESI协议这4个字母代表4个状态,分别是:Modified(已修改)、Exclusive(独占)、Shared(共享)、Invalidated(已失效)