Java 5 и выше только. Предположим, многопроцессорный компьютер с общей памятью (вы, вероятно, используете его прямо сейчас).
Вот код для отложенной инициализации синглтона:
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;
}
}
Требуется ли объявить instance
volatile
, чтобы оптимизатор не переписывал getInstance () следующим образом (что было бы правильно в последовательной программе):
public static MySingleton getInstance() {
if (instance == null) {
synchronized (MySingleton.class) {
// instance must be null or we wouldn't be here (WRONG!)
instance = new MySingleton();
}
}
}
При условии, что оптимизатор не переписывает код, если instance
не объявлен, volatile
все еще гарантированно будет сброшен в память при выходе из блока synchronized
и считан из памяти, когда блок synchronized
введено?
РЕДАКТИРОВАТЬ: я забыл сделать статический getInstance (). Я не думаю, что это меняет достоверность ответов; Вы все знали, что я имел в виду.