gpt4 book ai didi

java - volatile 变量的读-修改-写操作如何做到线程安全

转载 作者:行者123 更新时间:2023-11-30 06:46:13 25 4
gpt4 key购买 nike

我正在阅读 JCIP,但无法理解 3.3.1 中的以下语句,

It is safe to perform read-modify-write operations on shared volatile variables as long as you can ensure that the volatile variable is only written from a SINGLE thread. In this case you are confining the modifications to a single thread to prevent race conditions, and the visibility guarantees for volatile variables ensures that other threads see the most up-to-date value.

即使 volatile 变量仅从单个线程写入,它怎么能不引发竞争条件呢?例如,如果线程 A 在 counter 为 1 时执行 counter++,则线程 B 可以在 counter+1 被写回内存之前进入,并且获取 counter 的陈旧值 1。如何确保“防止竞争条件”和“其他线程看到最新值”??

附注我知道有一个相同的问题 here ,但我没有找到任何令人满意的答案。

最佳答案

How can read-modify-write operations of volatile variables be thread safe

一般来说,他们不能。

您引用的文字说:

"It is safe to perform read-modify-write operations on shared volatile variables as long as you can ensure that the volatile variable is only written from a SINGLE thread."

这不是线程安全的意思。作为一般性声明。

Even if the volatile variable is only written from a single thread, how can it not raise race conditions?

好吧,读取线程没有竞争条件,因为它们只会看到最近写入的变量值。并且写入线程受正常执行规则约束,因此线程与自身之间不存在竞争条件。

How is that ensuring "prevent race conditions"?

见上文。如果有多个线程更新,您只能参加一场比赛。从竞争条件的定义来看,这是不言而喻的。

[and] "other threads see the most up-to-date value"?

这是 Java 内存模型对 volatile 指定的结果。读取 volatile 变量可以保证看到任何线程最近写入的值...。

If thread A performs, say, counter++ when counter is 1, thread B could get in just before counter+1 is written back to memory and get a stale value 1 of counter.

在那种情况下,不存在竞争条件。线程 B 正在查看最近写入的 counter 值。计数器尚未更新。这意味着 count++ 不是原子的。但是线程安全和原子性并不是一回事。原子是更强的保证。并且 JLS 明确指出 count++ 对于 volatiles 不是原子的。

现在(很明显)如果您的应用程序有 多个 由不同(单个)线程更新的共享 volatile 变量,那么前面段落中的简单推理可能会失效。

关于java - volatile 变量的读-修改-写操作如何做到线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47879414/

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