【问题标题】:What makes immutable objects to be published without safe publication techniques?是什么让不可变对象在没有安全发布技术的情况下发布?
【发布时间】:2013-06-08 14:42:23
【问题描述】:

即使不使用安全的发布习惯也可以发布不可变对象是什么意思?

我已阅读 Java 并发实践第 3 章,共享对象),但仍然无法理解语句:

不可变对象可以通过任何机制发布。

               V/S 

应该安全地发布有效的不可变对象。

编辑:我已经通过similar question on SO 和答案,但仍然无法理解如何安全地发布不可变对象,因为引用不可变对象的字段有可能被视为 null 或一些陈旧的值由外部线程进行的较早调用。

【问题讨论】:

  • 不可变对象本身可以安全发布,任何引用它的字段都不是不可变对象的一部分,因此没有相同的保证。
  • 它们不能改变,因此您可以将它们视为“常量”。对于任何常量,您都希望能够在没有并发问题的情况下发布。
  • @Trillian 但是在像 Java 这样的语言中,如果对安全发布对象的引用仍然过时,那么它的用途是什么?他们应该同步说该对象已安全发布,对吧?
  • 问题?线程安全,不多也不少。不可变对象本质上是线程安全的。这个概念非常重要,以至于 JSR 305 有一个 @Immutable 注释来装饰类。

标签: java multithreading concurrency final java-memory-model


【解决方案1】:

并非每个用例都需要在任何精确时刻看到一个新实例。考虑教科书示例:延迟初始化的单例,在每个线程中重新初始化比安全共享更便宜。在这种情况下,您可能会不安全地共享一个不可变实例,并且每个无法接收已存在副本的线程只会创建自己的。

至于术语:不安全的发布意味着它发生在数据竞争之下。 安全发布是相反的情况。

顺便说一句,java.lang.String 是一个实际上不可变对象的示例,它仍然可以不安全地共享。

【讨论】:

  • 我有两个后续问题:1)为什么说“在每个线程中重新初始化延迟初始化的单例比安全共享更便宜”?和 2)“不安全的发布意味着它发生在数据竞争下”。在这种情况下,什么是数据竞争?
  • "顺便说一句,java.lang.String 是一个有效不可变对象的示例,但它可以不安全地共享。"..String 不是不可变的示例,而不是有效地不可变?
  • String 不是不可变的,因为它的hashCode 属性是可变的。它实际上是不可变的,因为它的公开可观察行为是不可变的。
  • 1) 我说“延迟初始化的单例更便宜……”而不是“延迟初始化的单例,更便宜……”。语义差异:我将我的主题限制在那些初始化便宜的惰性初始化单例上,而不是声称所有惰性初始化单例初始化都很便宜。
  • 2) 数据竞争发生在持有对共享对象的引用的变量上。该变量不是volatile,它的读/写是在没有synchronized 块等协调机制的情况下发生的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-30
  • 1970-01-01
  • 2016-09-30
  • 2015-01-04
相关资源
最近更新 更多