java - 有效不可变对象(immutable对象)

标签 java concurrency immutability java-memory-model

我想确保我根据 Java 内存模型正确理解了“有效不可变对象(immutable对象)”的行为。

假设我们有一个可变类,我们希望将其发布为有效的不可变类:

class Outworld {
  // This MAY be accessed by multiple threads
  public static volatile MutableLong published;
}

// This class is mutable
class MutableLong {
  private long value;

  public MutableLong(long value) {
    this.value = value;
  }

  public void increment() {
    value++;
  }

  public long get() {
    return value;
  }
}

我们执行以下操作:

// Create a mutable object and modify it
MutableLong val = new MutableLong(1);
val.increment();
val.increment();
// No more modifications
// UPDATED: Let's say for this example we are completely sure
//          that no one will ever call increment() since now

// Publish it safely and consider Effectively Immutable
Outworld.published = val;

问题是: Java 内存模型是否保证所有线程都必须有 Outworld.published.get() == 3

根据 Java Concurrency In Practice 这应该是真的,但如果我错了,请纠正我。

3.5.3. Safe Publication Idioms

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; or
- Storing a reference to it into a field that is properly guarded by a lock.

3.5.4. Effectively Immutable Objects

Safely published effectively immutable objects can be used safely by any thread without additional synchronization.

最佳答案

是的。 MutableLong 上的写入操作之后是读取之前的 happens-before 关系(在 volatile 上)。

(一个线程可能会读取 Outworld.published 并将其不安全地传递给另一个线程。理论上,这可以看到更早的状态。实际上,我没有看到它发生。 )

关于java - 有效不可变对象(immutable对象),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10254456/

相关文章:

java - 任意键的锁定处理程序

Elasticsearch 聚合按每个桶的前一个结果过滤

java - 为什么要在 Java 中声明一个不可变类 final?

java - 如何最好地显示 JGraphX?

Java字符编码

java - 为什么我的代码在 ideone.com 中不起作用?

java - Netty:使用多个事件循环的并发问题

jsp - tomcat只能有两个并发

javascript - 我应该对仅具有函数的对象使用不变性吗?

java - 通过 SCEP 在 Java 中生成 CSR 请求