Я хочу, чтобы я правильно понял поведение «Эффективно неизменяемых объектов» в соответствии с моделью памяти 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. Safe Publication Idioms
Чтобы опубликовать объект безопасно, как ссылка на объект, так и состояние объекта должны быть видимыми для других потоков одновременно. Правильно построенный объект можно безопасно опубликовать:
- Инициализация ссылки на объект из статического инициализатора;
- Сохранение ссылки на него в поле volatile или AtomicReference;
- Сохранение ссылки на него в конечном поле правильно построенного объекта; или
- Сохранение ссылки на него в поле, которое должным образом защищено блокировкой.3.5.4. Эффективно Неизменяемые объекты
Безопасно опубликованные эффективно неизменяемые объекты могут быть безопасно использованы любой нитью без дополнительной синхронизации.
Просьба показать [* статический инициализатор *] (http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html), который устанавливает состояние объекта до того, как ссылка на него сделана видимой , – trashgod