gpt4 book ai didi

java - 如果我省略 Java 的 volatile 关键字会发生什么?

转载 作者:行者123 更新时间:2023-12-02 01:08:27 25 4
gpt4 key购买 nike

我刚刚了解到 volatile Java 中的关键字。

本质上,如果在一个 CPU 中读取或写入一个变量,那么它会保存在该 CPU 的缓存中,但不一定会立即写入内存。

在某些情况下,我将对象引用或原始变量传递给另一个线程,但我没有使用 volatile关键字,因为直到现在我才知道该关键字。

我相信,如果一个新线程第一次读取该变量,那么就没有问题。但是,如果我的理解是正确的,那么如果第二个线程更改了该变量,那么第一个线程的 CPU 可能会将其保存在缓存中并报告过时的值。这是对省略 volatile 的影响的真正理解吗?关键字?

示例:

  1. 线程 A 将对象的变量值设置为 "First" .
  2. 线程 B 第一次读取该变量的值。
  3. 线程 A 将值更改为 "Second" .
  4. 线程 B 此后不久再次读取该值,但它仍然报告 "First"因为CPU缓存。

这是省略 volatile 的主要后果吗?什么时候需要关键词?线程报告过时的值?

我的理解正确吗?另外,我愿意接受任何其他关于何时不需要需要使用 volatile 的建议。 由另一个线程访问的非最终变量的关键字。我知道何时使用它,但我需要充分了解何时不使用它。

最佳答案

这与Java内存模型以及一个线程如何观察另一个线程有关。在单个线程中,该线程中执行的操作的效果与其写入的顺序相同。如果另一个线程正在观察一个线程修改的变量,则第二个线程可能无法按照第一个线程执行这些变量的顺序看到对这些变量的修改。这可能是由于缓存或编译器对指令重新排序造成的。

同步块(synchronized block)包含一个将 cpu 缓存写入内存的内存屏障,并且编译器知道不要重新组织代码以跨同步块(synchronized block)边界移动内容,因此在同步块(synchronized block)之前发生的任何事情对于观察线程都是可见的。

对 volatile 变量的访问还包括内存屏障,因此如果线程写入 volatile 变量,则任何读取该变量的线程都将读取写入其中的最新值。

因此,一般来说,在进入同步块(synchronized block)之前,对非 volatile 变量所做的修改可能对其他线程不可见。对 volatile 变量所做的修改立即可见。

关于java - 如果我省略 Java 的 volatile 关键字会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59722311/

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