Двойная проверка блокировки — самый популярный подход для реализации потокобезопасных Singleton'ов в Java. Он использует ленивую инициализацию, чтобы отложить создание объекта до первого использования.
Паттерн проверяет экземпляр дважды — один раз без блокировки и один раз с блокировкой — чтобы минимизировать затраты на синхронизацию. Ключевое слово volatile обеспечивает видимость изменений между потоками.
class DoubleCheckSingleton {
private volatile HelloSingleton instance;
public HelloSingleton getInstance() {
HelloSingleton result = instance;
if (result == null) {
synchronized(this) {
result = instance;
if (result == null) {
result = new HelloSingleton();
instance = result;
}
}
}
return result;
}
}
Паттерн Bill Pugh Singleton использует внутренний статический вспомогательный класс для элегантной потокобезопасности без затрат на синхронизацию. Внутренний класс загружается только при первом вызове getInstance(), что обеспечивает автоматическую ленивую инициализацию.
public class SingletonBillPugh {
private static class InnerSingleton {
private static final SingletonBillPugh INSTANCE =
new SingletonBillPugh();
}
private SingletonBillPugh() {}
public static SingletonBillPugh getInstance() {
return InnerSingleton.INSTANCE;
}
}
Этот подход повсеместно считается лучшей практикой благодаря простоте и отсутствию затрат на синхронизацию.
Java enum'ы обеспечивают самую простую потокобезопасную реализацию Singleton. Значения enum'а глобально доступны и изначально потокобезопасны согласно спецификации языка Java.
public enum SingletonEnum {
INSTANCE;
public void doImplementation() {
// реализация здесь
}
}
Enum'ы также защищают от атак через reflection и автоматически обрабатывают сериализацию, что делает их идеальными для большинства случаев.
Ключевое слово volatile в double-checked locking гарантирует, что все потоки видят один и тот же reference на экземпляр благодаря гарантиям видимости памяти через границы потоков.
Новый — ещё не проверен сообществом
Вы