MST
星途 面试题库

面试题:Java中volatile关键字的可见性原理是什么

请详细阐述在Java内存模型中,volatile关键字是如何保证变量的可见性的,即一个线程对volatile变量的修改如何能及时被其他线程看到。
13.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

volatile关键字保证可见性原理

  1. 内存屏障机制

    • 当一个变量被声明为volatile时,在对volatile变量进行写操作时,JVM会在写操作后插入一个Store Memory Barrier(存储内存屏障)。这一屏障会确保写操作的结果立即刷新到主内存中,而不是暂时保留在处理器的缓存中。这样,其他处理器缓存中的该变量副本就会失效,因为主内存中的值已经更新。
    • 在对volatile变量进行读操作时,JVM会在读取操作前插入一个Load Memory Barrier(加载内存屏障)。这一屏障会确保在读取volatile变量之前,先从主内存中重新加载最新的值,而不是使用处理器缓存中可能过期的值。
  2. 缓存一致性协议

    • 现代多核处理器为了提高性能,每个处理器都有自己的缓存。当一个线程修改了volatile变量,通过上述的内存屏障将修改刷新到主内存后,根据缓存一致性协议(如MESI协议),其他处理器缓存中该变量的副本会被标记为无效。
    • 当其他线程要读取该volatile变量时,由于其缓存中的副本已无效,就必须从主内存中获取最新的值,从而保证了可见性。
  3. 禁止指令重排序

    • volatile变量还具有禁止指令重排序的特性。编译器和处理器为了优化程序性能,可能会对指令进行重排序,但volatile变量会限制这种重排序。
    • 对于volatile变量的写操作,其前面的普通写操作不能重排序到volatile写之后;对于volatile变量的读操作,其后面的普通读操作不能重排序到volatile读之前。这保证了对volatile变量的读写操作顺序与代码中的顺序一致,避免因指令重排序导致其他线程看到不一致的数据,从而进一步保证了可见性。