多线程Java volatile是否阻止缓存或强制执行写缓存?
我试图理解Java的volatile
关键字,即在一个带有CPU缓存的多线程程序中,写入一个易失性原子变量
我已经阅读了一些教程和Java语言规范,尤其是section 17.4.5 on "happens-before ordering"。我的理解是,当一个线程将一个新值写入一个可变变量时,更新后的值必须对读取该变量的其他线程可见。对我来说,这些语义可以通过以下两种方式之一实现:
线程可以在CPU缓存中缓存易失性变量,但对缓存中变量的写入必须立即刷新到主内存。换句话说,缓存是write-through
线程永远不能缓存易失性变量,必须在主内存中读写此类变量
方法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中使用哪种方法是正确的
相关的问题不回答我的问题:
Does Java volatile read flush writes, and does volatile write update reads
# 1 楼答案
这些保证只是您在语言规范中看到的。从理论上讲,写入易失性变量可能会迫使缓存刷新到主内存,也可能不会,可能是后续读取会迫使缓存刷新,或者在没有缓存刷新的情况下以某种方式导致缓存之间的数据传输。这种模糊是故意的,因为它允许未来可能的优化,如果更详细地阐述易变变量的机制,这种优化可能是不可能的
实际上,在当前的硬件中,这可能意味着,如果没有一致的缓存,写入易失性变量将迫使缓存刷新到主内存。当然,有了一致的缓存,就不需要这样的刷新了