Код: Выделить всё
public class Singleton {
private volatile static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
использовать оба метода, чтобы гарантировать соблюдение правила «случается перед».
====== Правило «случается перед» =================================
https://docs.oracle.com /javase/specs/jls/se21/html/jls-17.html#jls-17.4.5
Набор ребер синхронизации S достаточен, если это минимальный набор, такой что транзитивное замыкание S с порядком программы определяет все ребра, происходящие до выполнения. Этот набор уникален.
Из приведенных выше определений следует, что:
Разблокировка монитора происходит — перед каждой последующей блокировкой этого монитора.
Запись в изменяемое поле (§8.3.1.4) происходит перед каждым последующим чтением этого поля.
Вызов start() в потоке происходит — до того, как любые действия в запущенном потоке.
Все действия в потоке происходят — до того, как любой другой поток успешно вернется из join() в этом потоке.
Инициализация любого объекта по умолчанию происходит перед любыми другими действиями программы (кроме записи по умолчанию).
Когда программа содержит два конфликтующих доступа (§ 17.4.1), которые не упорядочены по принципу «произошло до», говорят, что они содержат гонку данных.
Подробнее здесь: https://stackoverflow.com/questions/788 ... ck-pattern
Мобильная версия