Ответ
Singleton — это порождающий шаблон проектирования, который гарантирует, что у класса существует только один экземпляр, и предоставляет к нему глобальную точку доступа.
Ключевые характеристики:
- Приватный конструктор: Предотвращает создание экземпляра извне с помощью оператора
new. - Статическое поле: Содержит единственный экземпляр класса.
- Публичный статический метод (например,
getInstance()): Возвращает этот экземпляр, создавая его при первом вызове (ленивая инициализация).
Базовый пример (НЕ потокобезопасный):
public class SimpleSingleton {
private static SimpleSingleton instance; // Статическое поле
private SimpleSingleton() { // Приватный конструктор
// Инициализация
}
public static SimpleSingleton getInstance() {
if (instance == null) {
instance = new SimpleSingleton(); // Ленивая инициализация
}
return instance;
}
}
Потокобезопасные реализации:
1. Double-Checked Locking (для производительности):
public class ThreadSafeSingleton {
// Ключевое слово volatile гарантирует видимость изменения переменной всеми потоками
private static volatile ThreadSafeSingleton instance;
private ThreadSafeSingleton() {}
public static ThreadSafeSingleton getInstance() {
if (instance == null) { // Первая проверка (без блокировки)
synchronized (ThreadSafeSingleton.class) {
if (instance == null) { // Вторая проверка (под блокировкой)
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
}
2. Инициализация при загрузке класса (проще и безопаснее):
public class EagerSingleton {
// Экземпляр создаётся при загрузке класса JVM
private static final EagerSingleton INSTANCE = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return INSTANCE; // Просто возвращаем готовый экземпляр
}
}
Использование: Классы-менеджеры (конфигурации, подключений к БД), логгеры, кэши, пулы потоков, где важен контроль над ресурсами.
Важно: В многопоточных средах и контейнерах (например, Spring) предпочтительнее использовать dependency injection для управления жизненным циклом «одиночных» объектов.