gpt4 book ai didi

java - 为什么 Volatile 变量不用于 Atomicity

转载 作者:行者123 更新时间:2023-11-29 06:58:14 25 4
gpt4 key购买 nike

来自 Javadocs

Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.

当对 volatile 变量所做的更改始终对任何其他线程可见时,那么为什么在多个线程写入该变量的情况下不能使用 volatile 变量。为什么 volatile 仅用于一个线程写入或读取该变量而另一个线程仅读取变量的情况?

如果更改始终对其他线程可见,那么假设如果线程 B 想要写入该变量,它将看到新值(由线程 A 更新)并更新它。而当线程A再次想要写的时候,它又会看到线程B更新后的值并写入到它里面。这到底是哪里出了问题?

简而言之,我无法理解这一点。

if two threads are both reading and writing to a shared variable, then using the volatile keyword for that is not enough. You need to use synchronization in that case to guarantee that the reading and writing of the variable is atomic.

最佳答案

volatile 可以很好地用于许多目的 — 但也有很多它不能用于的目的。例如,假设您有一个这样的字段:

private volatile int i;

和两个同时运行 ++this.i 的线程:读取 this.i 然后写入它。

问题是 ++this.i 是一个 volatile 读取,后面跟着一个完全独立的 volatile 写入。在读取和写入之间可能发生任何事情;特别是,您可能会遇到这样一种情况,即两个线程都在写入 i 之前读取它。最终效果是 i 的值只增加了 1,即使两个独立的线程都增加了它。

AtomicInteger(和其他原子)通过允许您在单个原子(≈ volatile)步骤中同时读取和写入来解决此类问题。 (他们通过使用比较和交换指令来实现这一点,该指令仅在读取的值仍然是当前值时才执行写入。递增和获取方法只是运行一个循环来重试此操作,直到写入真正成功。 )

关于java - 为什么 Volatile 变量不用于 Atomicity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30430128/

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