发生在Volatile中的Happens before保证

huangapple go评论72阅读模式
英文:

Happens before guarantee in Volatile

问题

在阅读《Java并发编程实践》时,我遇到了与Happens before guaranteeVolatile相关的以下陈述:

当两个线程使用共同的锁进行同步时,会出现先于关系。线程A内的所有操作都按照程序顺序规则排序,线程B内的操作也是如此。因为A释放了锁M,随后B获取了M,所以在释放锁之前A中的所有操作都会在获取锁之后的B中的操作之前排序。当两个线程在不同的锁上同步时,我们无法确定它们之间操作的顺序,两个线程之间不存在先于关系。

有人可以详细解释一下这究竟是什么意思吗?

英文:

While going through the Java Concurrency in Practice I came across the below statement related to the Happens before guarantee that Volatile provides

> Happens before relation when two threads synchronize using a common
> lock. All the actions within thread A are ordered by the program order
> rule, as are the actions within thread B. Because A releases lock M
> and B subsequently acquires M, all the actions in A before releasing
> the lock are therefore ordered before the actions in B after acquiring
> the lock. When two threads synchronize on different locks, we can't
> say anything about the ordering of actions between them there is no
> happens before relation between the actions in the two threads.

Can someone please elaborate a bit more on what exactly does this mean?

答案1

得分: 2

> 有人能否详细解释一下这究竟是什么意思?

引用的文字涉及原始锁的语义。

基本上它表示,如果线程 A 在持有锁 M 的同时写入一个共享变量 V,然后释放该锁,然后线程 B 获取锁 M 并读取共享变量 V,那么它在读取之前不会看到 V 的值在 A 写入之前的任何值。

然而,它不一定会看到 A 写入的值,因为有可能另一个 C 线程写入了 V:

  • 如果 C 在持有锁 M 的同时写入了 V,则当 C 的写入时间在 A 的写入之前时,B 将看到 A 的值。

  • 如果 C 在没有持有锁的情况下写入了 V,则不确定 B 的读取将看到什么值。

volatile 的语义要简单一些。如果 Avolatile 变量 V 写入一个值,然后如果 BA 写入后读取 V,那么它在读取之前不会看到 VA 写入之前的任何值。(它将看到 A 写入的内容,或者是在 A 写入时或之后某个其他线程写入的内容。)

英文:

> Can someone please elaborate a bit more on what exactly does this mean?

The quoted text is about the semantics of primitive locks.

Basically it says that if thread A writes to a shared variable V while holding a lock M, and then releases the lock, and then thread B acquires lock M and reads the shared variable V, then it will not see the value of V before the either before it was written by A.

It won't necessarily see the value written by A though because it is possible that another C thread wrote to V:

  • If C wrote to V while holding the lock M, then B will see A's value if C's write was at a point in time before A's write.

  • If C wrote to V without holding the lock, then it is unspecified what value B's read will see.

The semantics of volatile are a bit simpler. If A writes a value to volatile V, and then if B reads V after As write then it won't see the value of V before A's write. (It will either see what A wrote, or something written by some other thread at or after the time of A's write.)

答案2

得分: 1

关于volatile修饰符的问题。

自从Java 6(我想是这样)以来,对于volatile变量, Happens Before行为发生了改变。

写入volatile变量在发生在读取volatile变量之前。这意味着例如您有一个volatile int foo,那么如果任何线程写入此变量,这些更改将绝对对另一个读取可见。换句话说,如果您向volatile变量写入内容,它将立即与主内存同步(而不仅仅保留在本地线程缓存中)。

英文:

In case you asking about volatile modificator.

Since Java 6 (I think) Happens Before behavior was changed for volatile variable.

Writting to volatile variable is happens before reading volatile variable. It means that e.g. you have volatile int foo, then if any thread writes to this variable, this changes will be definitely visible for another read. Another words, if you write smth. to volatile variable, it will be immideately synchronised with main memory (and not leaving in local thread cache only).

huangapple
  • 本文由 发表于 2020年10月18日 19:36:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/64412838.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定