问题描述
我正在阅读JCIP,但无法理解3.3.1中的以下声明,
I'm reading JCIP and am having trouble understand the following statement in 3.3.1,
即使volatile变量仅是从单个线程写入的,它怎么也不能提高竞争条件?如果线程A在counter
为1时执行counter++
,则线程B可以在counter+1
写回内存之前进入,并获得counter
的陈旧值1.如何确保防止竞争条件"和其他线程看到最新值"?
Even if the volatile variable is only written from a single thread, how can it not raise race conditions? 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
. How is that ensuring "prevent race conditions" and "other threads see the most up-to-date value"??
p.s.我知道有一个相同的问题这里,但是我没有找到满意的答案.
p.s. I know there's a same question here, but I didn't find any satisfying answer.
推荐答案
通常,他们不能.
您引用的文字说:
这不是线程安全的意思.作为一般性声明.
That is NOT what thread safe means. As a general statement.
那么,读取线程没有竞争条件,因为它们只会看到变量的最新写入值.而且编写线程受正常执行规则支配,因此线程与其自身之间不会存在竞争条件.
Well, there are no race conditions for the reading threads because they will only see the most recently written value of the variable. And the writing thread is governed by normal execution rules, so there can't be a race condition between the thread and itself.
请参见上文.如果有多个线程更新,则只能参加比赛.从种族条件的定义来看,这是不言而喻的.
See above. You can only get a race if there is more than one thread updating. It is self-evident from the definition of a race condition.
这是Java内存模型指定的关于volatile
的结果.保证可以通过任何线程读取volatile变量来查看最近的先前write ...的值.
That is a consequence of what the Java memory model specifies about volatile
. A read of a volatile variable is guaranteed to see the value of the most recent preceding write ... by any thread.
在这种情况下,没有竞争条件.线程B正在看到最新写入的counter
值.计数器尚未更新.这意味着count++
不是原子.但是线程安全和原子并不意味着同一件事.原子是一个更有力的保证.而且JLS明确指出,count++
对于挥发物不是原子的.
In that scenario, there is no race condition. Thread B is seeing the most recently written value of counter
. The counter has not been updated yet.That means that count++
is not atomic. But thread-safe and atomic do not mean the same thing. Atomic is a stronger guarantee. AND the JLS clearly states that count++
is not atomic for volatiles.
现在(很明显),如果您的应用程序具有由多个(单个)线程更新的多个共享易失变量,那么前几段的简单原因可能会崩溃.
Now (obviously) if your application has multiple shared volatile variables being updated by different (single) threads, then the simple reasoning of the previous paragraphs can break down.
这篇关于可变变量的读-修改-写操作如何保证线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!