Фактически неизменяемый объект

Я хочу убедиться, что правильно понимаю поведение «эффективно неизменяемых объектов» в соответствии с моделью памяти Java.

Допустим, у нас есть изменяемый класс, который мы хотим опубликовать как эффективно неизменяемый:

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. Идиомы безопасной публикации

Для безопасной публикации объекта и ссылка на объект, и состояние объекта должно быть сделано видимым для других потоков одновременно. Правильно сконструированный объект можно безопасно опубликовать с помощью:
-Инициализации ссылки на объект из статического инициализатора;
-Сохранение ссылки на него в volatile поле или AtomicReference;
-Сохранение ссылки на него в конечном поле корректно сконструированного объекта; или
-Сохранение ссылки на него в поле, которое должным образом защищено блокировкой.

3.5.4. Эффективно неизменяемые объекты

Безопасно опубликованные эффективно неизменяемые объекты могут безопасно использоваться любой поток без дополнительной синхронизации.

10
задан reevesy 9 May 2012 в 05:04
поделиться