gpt4 book ai didi

java - Java 如何管理 volatile 字段的可见性?

转载 作者:行者123 更新时间:2023-12-01 07:59:38 25 4
gpt4 key购买 nike

这个问题正在寻找有关 Java 如何使 volatile 字段可见的具体细节。

Java 中的 volatile 关键字用于使变量在写入操作完成后立即对该变量的读取者“主动”可见。这是先发生关系的一种形式——使写入结果暴露给访问该变量的内存位置以供某些用途的任何人。使用时,使对该变量的读/写操作成为原子的——对于 long 和 double 来说——对所有其他 var 类型的读/写操作已经是原子的。

我想了解 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
}
}

对 boolean 文字的读取和写入是原子的。如果调用上面的 close() 方法,则将 close 的值设置为 true 是一个原子操作,即使它不是声明为 volatile

这段代码中 volatile 所做的更多事情是确保该值的更改在发生时立即可见。

volatile 究竟是如何实现这一目标的?

通过优先考虑对 volatile 变量进行操作的线程?如果是这样 - 如何在线程调度中,或者通过使具有读取操作的线程查找标志来查看是否有写入线程挂起?我知道“对 volatile 字段的写入发生在同一字段的每次后续读取之前”。是否在线程中选择对 volatile 变量进行写操作的线程,然后再将 CPU 时间分配给仅读取的线程?

如果这是在线程调度级别进行管理的(我对此表示怀疑),那么运行一个对 volatile 字段进行写入的线程会产生比看起来更大的影响。

Java 到底是如何管理 volatile 变量的可见性的?

TIA。

最佳答案

这是OpenJDK源代码中关于 volatile 的注释

// ----------------------------------------------------------------------------
// Volatile variables demand their effects be made known to all CPU's
// in order. Store buffers on most chips allow reads & writes to
// reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
// without some kind of memory barrier (i.e., it's not sufficient that
// the interpreter does not reorder volatile references, the hardware
// also must not reorder them).
//
// According to the new Java Memory Model (JMM):
// (1) All volatiles are serialized wrt to each other. ALSO reads &
// writes act as aquire & release, so:
// (2) A read cannot let unrelated NON-volatile memory refs that
// happen after the read float up to before the read. It's OK for
// non-volatile memory refs that happen before the volatile read to
// float down below it.
// (3) Similar a volatile write cannot let unrelated NON-volatile
// memory refs that happen BEFORE the write float down to after the
// write. It's OK for non-volatile memory refs that happen after the
// volatile write to float up before it.
//
// We only put in barriers around volatile refs (they are expensive),
// not _between_ memory refs (that would require us to track the
// flavor of the previous memory refs). Requirements (2) and (3)
// require some barriers before volatile stores and after volatile
// loads.

希望对您有所帮助。

关于java - Java 如何管理 volatile 字段的可见性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26204900/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com