Вопрос

в модели памяти Java упоминается, что:Когда поток выходит из синхронизированного блока в рамках освобождения связанного монитора, JMM требует, чтобы кэш локального процессора был сброшен в основную память.Сходным образом, в рамках получения монитора при входе в синхронизированный блок локальные кэши становятся недействительными, поэтому последующие операции чтения будут идти непосредственно в основную память, а не в локальный кэш.

так почему в этом коде я должен объявить экземпляр как изменчивый, поскольку, когда второй поток входит в блок синхронизации, он перейдет непосредственно в основную память??

public final class MySingleton {
  private static MySingleton instance = null;
  private MySingleton() { } 
  public static MySingleton getInstance() {
    if (instance == null) {
      synchronized (MySingleton.class) {
        if (instance == null) {
          instance = new MySingleton();
        }
      }
    }
    return instance;
  }
}

Я имею в виду, что когда другой поток входит в блок синхронизации и выполняет вторую проверку, он должен обновляться из основной памяти, как уже упоминалось.

Это было полезно?

Решение

Состояние гонки следующее:

  1. Поток А видит instance == NULL и запускает этот код instance = new MySingleton();.Напишите в instance видно, но запись в MySingleton еще нет.

  2. Поток B видит instance != NULL и начинает работать над экземпляром.

  3. Поток B сейчас работает над объектом, конструкцию которого он не видит.

Изготовление instance Летучий решает проблему, поскольку спецификация памяти JDK, начиная с JDK5, гарантирует, что запись в энергонезависимые объекты не будет нарушена по порядку по сравнению с записью в энергозависимый объект.Поэтому любой поток, который видит instance != NULL должен видеть сам экземпляр.

Другие советы

Вы должны объявить его нестабильным, в противном случае нет никакой гарантии, что два вызова на GetInstance () вернут один и тот же экземпляр.

Нет гарантии, что доступная основная память будет доступна только последовательное значение кэша.I.e. Все темы увидят одинаковое значение.

BTW: Вы знаете, конечно, его гораздо более сложный, чем необходимо.Все, что вам нужно, это

public enum MySingleton {
     INSTANCE;
}
.

делает много одно и то же.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top