Ответ
Один из самых распространенных — Singleton (Одиночка). Он гарантирует существование только одного экземпляра класса и предоставляет глобальную точку доступа к нему.
Типичное применение: Логгеры, конфигурации, пулы соединений, кэши.
Базовая реализация (ленивая, но не потокобезопасная):
public class Singleton {
private static Singleton instance;
private Singleton() {} // Приватный конструктор
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Проблема при многопоточности
}
return instance;
}
}
Потокобезопасные реализации:
synchronizedметод (просто, но медленно):public static synchronized Singleton getInstance() { ... }- Double-Checked Locking (оптимизировано):
public class Singleton { private static volatile Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } } - Через
enum(рекомендовано Джошуа Блохом, потокобезопасно и сериализуемо):public enum Singleton { INSTANCE; public void doSomething() { ... } } // Использование: Singleton.INSTANCE.doSomething();
Почему enum — лучший выбор? JVM гарантирует единственность экземпляра, автоматически обрабатывает сериализацию и защищает от рефлексивных атак.
Ответ 18+ 🔞
А, Синглтон, классика жанра, ёпта! Этот паттерн — как тот одинокий мужик на районе, который всем нужен, но он такой один, блядь, и больше никого не пускает. Логгер там, конфиг какой-нибудь — везде он, сука, главный по тарелочкам.
Смотри, как его на коленке слепить можно, если похуй на потоки (а на потоки похуй бывает только в однопоточном приложении, которых уже, как говна за баней):
public class Singleton {
private static Singleton instance;
private Singleton() {} // Спрятал конструктор, хитрая жопа!
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // А вот тут два потока могут влететь и наделать овердохуища экземпляров!
}
return instance;
}
}
Ну и кто так делает? Только полные пидарасы, блядь. Потоки же налетят — и пиздец твоей уникальности.
Поэтому народ извращается, как может:
-
Тупо и медленно, зато надёжно, как мамин тапок. Весь метод на замок:
public static synchronized Singleton getInstance() { ... }Работать будет, но каждый раз этот замок-блядь — терпения ебать ноль, если вызывают часто.
-
Double-Checked Locking — для умных и хитрых. Сначала глянул без замка, потом, если надо, с замком, и ещё раз глянул:
public class Singleton { private static volatile Singleton instance; // volatile, ёпта, это важно, а то оптимизатор начудит! private Singleton() {} public static Singleton getInstance() { if (instance == null) { // Первая проверка (быстрая) synchronized (Singleton.class) { // Замок if (instance == null) { // Вторая проверка (уже под замком, тут всё серьёзно) instance = new Singleton(); } } } return instance; } }Уже лучше, блядь, но всё равно пахнет подвохом для новичков.
-
А теперь, блядь, венцом творения —
enum! Джошуа Блох, тот ещё мудила умный, так сказал делать. И он прав, ёпта:public enum Singleton { INSTANCE; // Всё, пиздец. Он один. JVM сама за этим следит, как сука. public void doSomething() { ... } } // Берёшь и юзаешь: Singleton.INSTANCE.doSomething();
Почему enum — это ядрёна вошь? Да потому что JVM сама, блядь, гарантирует, что этот INSTANCE будет в единственном экземпляре. И сериализация с ним не сломается, и через рефлексию его не сломаешь. Красота, блядь, а не решение. В рот меня чих-пых, иногда умные люди и правду говорят.