有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java volatile是否阻止缓存或强制执行写缓存?

我试图理解Java的volatile关键字,即在一个带有CPU缓存的多线程程序中,写入一个易失性原子变量

我已经阅读了一些教程和Java语言规范,尤其是section 17.4.5 on "happens-before ordering"。我的理解是,当一个线程将一个新值写入一个可变变量时,更新后的值必须对读取该变量的其他线程可见。对我来说,这些语义可以通过以下两种方式之一实现:

  1. 线程可以在CPU缓存中缓存易失性变量,但对缓存中变量的写入必须立即刷新到主内存。换句话说,缓存是write-through

  2. 线程永远不能缓存易失性变量,必须在主内存中读写此类变量

方法1在这篇{a3}({a4})中提到,它说:

By declaring the counter variable volatile all writes to the counter variable will be written back to main memory immediately.

方法2在一个Stackoverflow问题“Volatile variable in Java”中提到,这个tutorial也表示:

The value of this variable will never be cached thread-locally: all reads and writes will go straight to "main memory"

在Java中使用哪种方法是正确的

相关的问题不回答我的问题:

Volatile variable in Java

Does Java volatile read flush writes, and does volatile write update reads

Java volatile and cache coherence


共 (1) 个答案

  1. # 1 楼答案

    这些保证只是您在语言规范中看到的。从理论上讲,写入易失性变量可能会迫使缓存刷新到主内存,也可能不会,可能是后续读取会迫使缓存刷新,或者在没有缓存刷新的情况下以某种方式导致缓存之间的数据传输。这种模糊是故意的,因为它允许未来可能的优化,如果更详细地阐述易变变量的机制,这种优化可能是不可能的

    实际上,在当前的硬件中,这可能意味着,如果没有一致的缓存,写入易失性变量将迫使缓存刷新到主内存。当然,有了一致的缓存,就不需要这样的刷新了