挥发性保证安全发布可变对象? [英] Volatile guarantee safe publication of a mutable object?

查看:156
本文介绍了挥发性保证安全发布可变对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过阅读实践中的Java并发



我可以看到:



要安全地发布对象,必须同时使对象的引用和对象的状态对其他线程可见。正确构造的对象可以通过以下方式安全地发布:




  • 从静态初始化程序初始化对象引用

  • 将对它的引用存储到易失性字段或AtomicReference中

  • 将对它的引用存储到正确构造的对象的最终字段中

  • 存储a引用它进入一个由
    锁正确保护的字段。



然而,我对第二个成语感到困惑。由于 volatile 只能保证引用对另一个线程可见,但是它没有引用的对象构造的同步即可。那么如何保证可变对象被正确构造,构造该对象的线程被另一个线程中断了?

解决方案

我们需要证明构造一个对象并将其分配给一个volatile变量是在从该变量读取之前发生的。 / p>

来自JLS第17章:


如果 x y 是同一个线程的动作,而 x 是按照程序顺序出现在 y 之前,然后是 hb(x,y)。


因此,对象的构造发生在之前,它被分配给一个volatile变量,从它的角度来看线程。


如果某个操作 x与同步,则执行以下操作 y, 然后我们还有 hb(x,y)。


并且:


如果 hb(x,y) hb(y,z),那么 hb(x,z)。


如果我们可以证明写入volatile变量(action y 同步 - 读取变量(action z ),我们可以使用发生在之前的传递性来表明构造对象(action x 读取对象之前发生。幸运的是:


写入易失性变量 v (§8.3.1.4)同步 - 任何线程对 v 的所有后续读取(其中后续根据同步顺序定义)。


因此,我们可以看到,当以这种方式发布时,任何线程都可以看到正确构造的对象。


By reading Java Concurrency in Practice

I can see:

To publish an object safely, both the reference to the object and the object's state must be made visible to other threads at the same time. A properly constructed object can be safely published by:

  • Initializing an object reference from a static initializer
  • Storing a reference to it into a volatile field or AtomicReference
  • Storing a reference to it into a final field of a properly constructed object
  • Storing a reference to it into a field that is properly guarded by a lock.

However, I am confused about the second idiom. Since volatile can only guarantee that the reference is visible to another thread but it doesn't have synchronization of object construction which it refers to. So how can it guarantee that the mutable object is properly constructed, what is the thread that is constructing this object is interrupted by another thread?

解决方案

We need to show that constructing an object and assigning it to a volatile variable happens before it is read from that variable.

From JLS Chapter 17:

If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).

So, construction of an object happens before it is assigned to a volatile variable, from the point of view of that thread.

If an action x synchronizes-with a following action y, then we also have hb(x, y).

And:

If hb(x, y) and hb(y, z), then hb(x, z).

If we could show that writing the volatile variable (action y) synchronizes-with reading the variable (action z), we could use the transitivity of happens-before to show that constructing the object (action x) happens-before reading the object. Luckily:

A write to a volatile variable v (§8.3.1.4) synchronizes-with all subsequent reads of v by any thread (where "subsequent" is defined according to the synchronization order).

Therefore, we can see that a properly constructed object is visible to any thread when published this way.

这篇关于挥发性保证安全发布可变对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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