面试题答案
一键面试volatile关键字保证可见性原理
-
内存屏障机制
- 当一个变量被声明为
volatile
时,在对volatile
变量进行写操作时,JVM会在写操作后插入一个Store Memory Barrier(存储内存屏障)。这一屏障会确保写操作的结果立即刷新到主内存中,而不是暂时保留在处理器的缓存中。这样,其他处理器缓存中的该变量副本就会失效,因为主内存中的值已经更新。 - 在对
volatile
变量进行读操作时,JVM会在读取操作前插入一个Load Memory Barrier(加载内存屏障)。这一屏障会确保在读取volatile
变量之前,先从主内存中重新加载最新的值,而不是使用处理器缓存中可能过期的值。
- 当一个变量被声明为
-
缓存一致性协议
- 现代多核处理器为了提高性能,每个处理器都有自己的缓存。当一个线程修改了
volatile
变量,通过上述的内存屏障将修改刷新到主内存后,根据缓存一致性协议(如MESI协议),其他处理器缓存中该变量的副本会被标记为无效。 - 当其他线程要读取该
volatile
变量时,由于其缓存中的副本已无效,就必须从主内存中获取最新的值,从而保证了可见性。
- 现代多核处理器为了提高性能,每个处理器都有自己的缓存。当一个线程修改了
-
禁止指令重排序
volatile
变量还具有禁止指令重排序的特性。编译器和处理器为了优化程序性能,可能会对指令进行重排序,但volatile
变量会限制这种重排序。- 对于
volatile
变量的写操作,其前面的普通写操作不能重排序到volatile
写之后;对于volatile
变量的读操作,其后面的普通读操作不能重排序到volatile
读之前。这保证了对volatile
变量的读写操作顺序与代码中的顺序一致,避免因指令重排序导致其他线程看到不一致的数据,从而进一步保证了可见性。