gpt4 book ai didi

Java volatile变量影响其他非volatile变量的内存一致性

转载 作者:行者123 更新时间:2023-11-29 08:36:31 24 4
gpt4 key购买 nike

场景A

A1。写入 volatile 变量

A2。刷新所有本地非 volatile 变量写入到主内存

场景 B

B1。从 volatile 变量中读取

B2。将所有非 volatile 变量从主存重新加载到本地内存

  • 场景 A 和 B 是涉及 volatile 的正确行为吗变量?或者场景A是否也包含B2,或者场景B是否也包含还包括A2?
  • 这些场景是原子的吗?会不会有其他事情发生在A1和A2之间?还是 B1 和 B2?

(使用 Java 1.8/1.5+)

最佳答案

写入 volatile 变量保证刷新非 volatile 变量1。但是,它会在对 volatile 的写入和对 volatile 的任何后续读取之间引入“发生在之前”的关系(假设没有对其进行干预写入)。您可以按如下方式利用它:

  1. 线程A:写NV
  2. 线程A:写入V
  3. 线程 B : 读取 V
  4. 线程 B : 读取 NV

如果操作按该顺序发生,则线程 B 将在步骤 4 中看到 NV 的更新值。但是,如果某些东西(包括 A)在步骤 2 之后写入 NV,则线程 B 将在步骤 4 中看到什么是不确定的.

一般来说,以这种方式使用 volatiles 需要深入而仔细的推理。使用 synchronized 更容易也更健壮。


你的例子不清楚:

  • 如果它旨在描述 Java 程序员必须做什么,那是错误的/荒谬的。 Java 代码不能刷新变量。

  • 如果它旨在成为在实现级别(例如在 JIT 编译代码中)必须发生的事情的规范,那也是错误的。

  • 如果它旨在描述在实现级别(例如在 JIT 编译代码中)可能发生的事情,那么它是正确的。

我不只是在这里学究气。编译器可能会决定它不需要刷新线程 A 中的所有 局部非 volatile 变量,并且它很可能只会重新加载它在线程 B 中需要的那些。它是如何决定的?那是编译器作者的事!


1 - JLS 不需要硬件特定的操作,例如刷新。相反,它要求编译后的代码满足一些特定的内存可见性保证,并将实现留给编译器编写者。

关于Java volatile变量影响其他非volatile变量的内存一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43712673/

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