【发布时间】:2014-10-05 16:50:01
【问题描述】:
这个 Q 正在寻找有关 Java 如何使 volatile 字段可见的具体细节。
Java 中的volatile 关键字用于在对变量执行写操作后立即使该变量的读取器“主动”可见。这是一种先发生关系的形式——使写入的结果暴露给访问该变量的该内存位置以供某些用途的任何人。并且当使用时,使对该变量的读/写操作具有原子性——对于long 和double 也是如此——对所有其他 var 类型的 R/W 已经是原子的。
我正在寻找 Java 在写操作后如何使变量值可见?
例如:以下代码来自this讨论的答案之一:
public class Foo extends Thread {
private volatile boolean close = false;
public void run() {
while(!close) {
// do work
}
}
public void close() {
close = true;
// interrupt here if needed
}
}
对布尔文字的读写是原子的。如果调用了上面的方法close(),即使没有声明为volatile,将close的值设置为true也是一个原子操作。
volatile 在此代码中所做的更多工作是确保在更改此值时立即看到它。
volatile 究竟是如何实现这一目标的?
通过优先处理对 volatile 变量进行操作的线程?如果是这样-如何在线程调度中,或者通过使具有读取操作的线程去查找一个标志以查看是否有写入线程挂起?我知道“对易失性字段的写入发生在每次后续读取同一字段之前。”是否在线程中进行选择,即在将 CPU 时间分配给只读线程之前对 volatile 变量进行写操作的线程?
如果这是在线程调度级别进行管理的(我对此表示怀疑),那么运行一个在 volatile 字段上写入的线程会产生比看起来更大的效果。
Java 究竟如何管理volatile 变量的可见性?
TIA。
【问题讨论】:
-
它保证写入 volatile 变量的线程将写入主内存,而不是写入处理器缓存,并且读取 volatile 变量值的线程不会从处理器读取它缓存,但来自主内存。我不是这些低级硬件机制的专家,所以我会让专家回答,但你应该明白。与日程安排或优先级无关。
-
CPU 完成所有工作。 JVM 确保它使用正确的指令。
标签: java multithreading volatile happens-before