有效的不可变对象 [英] Effectively Immutable Object

查看:71
本文介绍了有效的不可变对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确保根据Java内存模型正确理解有效不可变对象"的行为.

I want to make sure that I correctly understand the 'Effectively Immutable Objects' behavior according to Java Memory Model.

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

Let's say we have a mutable class which we want to publish as an effectively 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?


The question is: Does Java Memory Model guarantee that all threads MUST have Outworld.published.get() == 3 ?

根据 Java并发实践 ,这应该是正确的,但是请纠正我我错了.

According to Java Concurrency In Practice this should be true, but please correct me if I'm wrong.

3.5.3.安全出版惯用语

3.5.3. Safe Publication Idioms

要安全地发布对象,请同时引用该对象和 对象的状态必须同时对其他线程可见. 可以通过以下方式安全地发布正确构造的对象:
-从静态初始值设定项初始化对象引用;
-将对它的引用存储到volatile字段或AtomicReference中;
-将对它的引用存储到正确构造的对象的最终字段中;或
-将对其的引用存储到由锁适当保护的字段中.

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.有效的不可变对象

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上).

Yes. The write operations on the MutableLong are followed by a happens-before relationship (on the volatile) before the read.

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

(It is possible that a thread reads Outworld.published and passes it on to another thread unsafely. In theory, that could see earlier state. In practice, I don't see it happening.)

这篇关于有效的不可变对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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