可变变量的读-修改-写操作如何保证线程安全 [英] How can read-modify-write operations of volatile variables be thread safe

查看:124
本文介绍了可变变量的读-修改-写操作如何保证线程安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm reading JCIP and am having trouble understand the following statement in 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.如何确保防止竞争条件"和其他线程看到最新值"?

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.

推荐答案

可变变量的读-修改-写操作如何保证线程安全

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

通常,他们不能.

您引用的文字说:

只要您可以确保仅从单个线程写入volatile变量,就可以对共享的volatile变量执行读-修改-写操作."

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

That is NOT what thread safe means. As a general statement.

即使volatile变量仅是从单个线程写入的,它怎么也不能提高竞争条件?

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

那么,读取线程没有竞争条件,因为它们只会看到变量的最新写入值.而且编写线程受正常执行规则支配,因此线程与其自身之间不会存在竞争条件.

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.

如何确保预防比赛条件"?

How is that ensuring "prevent race conditions"?

请参见上文.如果有多个线程更新,则只能参加比赛.从种族条件的定义来看,这是不言而喻的.

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.

[和]其他线程看到的是最新值"?

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

这是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.

如果线程A在计数器为1时执行counter ++,则线程B可以在将counter + 1写回内存之前获得计数器的过时值1.

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++对于挥发物不是原子的.

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.

这篇关于可变变量的读-修改-写操作如何保证线程安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆