安全出版没有发生 - 之前?无论如何除了最后?

时间:2011-03-28 12:16:48

标签: java multithreading concurrency visibility

根据JCP(16.2.2。安全出版物):

  

这种情况发生之前 - 保证实际上是一种更强的可见性和排序承诺,而不是安全发布。当X安全地从A发布到B时,安全发布保证了X的状态的可见性,但不保证A可能触及的其他变量的状态。但是如果A在队列中放置X,那么在B从该队列中取出X之前,不仅B在A离开它的状态下看到X(假设X后来没有被A或其他任何人修改过),但B看到A在切换之前所做的一切(再次,同样需要注意)

我想知道安全发布何时可能没有发生 - 即使用volatile / atomics或同步(或通过使用内部列出的任何内容的AQS等框架)?

一个案例是不可变对象中的最终字段,您可以按照任何其他步骤将其发布。

还有其他案件吗?

UPD:重新阅读3.5.3。安全发布惯用语,另一种情况 - “从静态初始化程序初始化对象引用”。现在看来这些都是选择。

3 个答案:

答案 0 :(得分:2)

final之外,我不知道任何事情,只需看一眼http://java.sun.com/docs/books/jls/third_edition/html/memory.html就可以证实这一点。第17.4章处理除final之外的所有内容,这在17.5中单独解释。

但应该注意的是,JVM内部的任何内容必须始终可见,然后才能在Java代码中引发数据竞争。这主要影响数组长度,虚拟表指针和字符串内容。这些永远不会被视为未初始化或不一致。

答案 1 :(得分:2)

您可以在Java In Concurrency中找到的所有案例列表:

  

安全地发布对象,两者都是   引用对象和   必须使对象的状态可见   其他线程同时。一个   正确构造的对象可以   安全发布者:

     

初始化对象引用   静态初始化器;

     

将对它的引用存储到   volatile字段或AtomicReference;

     

将参考文献存入决赛   正确建造的领域   宾语;或

     

将对它的引用存储到字段中   这是由一把锁妥善保护的。

答案 2 :(得分:1)

静态初始化在synchronized(class)内完成,所以非常强大。

虽然final语义较弱,但我怀疑实现是否真的那么弱。

Doug Lea提出了更原始的围栏,http://cs.oswego.edu/pipermail/concurrency-interest/2009-January/005743.html