Синглетон (одиночка) в Java

Синглетон — это класс, у которого существует только один экземпляр, к которому предоставляется доступ через одну глобальную точку доступа. Важно, что есть только один экземпляр объекта, а не просто набор методов.

Плюсы и минусы синглетонов

Плюсы:

  • Контролируемый доступ к единственному экземпляру (например, логгера или игрового мира).

Минусы:

  • Усложняет написание тестов.
  • Усложняет развитие ПО, если в дальнейшем окажется, что нужно иметь несколько экземпляров этого объекта.

Примеры реализаций синглетонов в Java

Вариант 1

Самый простой. Создание экземпляра фактически будет происходить при первом обращении к любому поли или методу класса Singleton (не обязательно к методу getInstance()). Потокобезопасен.

 

Вариант 2

Несинхронизированный вариант. Только для однопоточных  приложений.

Вариант 3

Несинхронизированный вариант с возможностью обработки исключений создания экземпляра и неленивой инициализацией. Создание экземпляра будет происходить при первом доступе к полю или методу класса Singleton, то есть для случая, когда кроме метода getInstance() в нём нет других публичных методов и полей, этот вариант вполне можно считать вариантом с отложенной инициализацией.

 

Вариант 4

Использование static synchronized  метода для синхронизации доступа к экземпляру и его создания. Из недостатков можно отметить, что этот способ блокирует метод getInstance() не зависимо от того, создали мы уже экземпляр или нет, что замедляет работу при использовании нескольких потоков. Подробнее про модификатор synchronized  я уже описывал в статье про многопоточность в Java.

Вариант 5

Вариант с вложенным блоком synchronized и повторной проверкой существования экземпляра. Лишён недостатка предыдущего метода. Модификатор volatile  для поля instance нужен, чтобы запись в переменную была видна целиком из других потоков.

Вариант 6

Ленивая инициализация без необходимости синхронизации. Основная хитрость этого способа состоит в том, что при вызове Singleton.getInstance()  класс SingletonHolder  ещё не будет загружен и инициализирован, а значит экземпляр будет создаваться только при обращении к getInstance(). А хитрость отсутствия необходимости инициализации в том, что загрузка и инициализация класса в любом случае будет проходить ClassLoader-ом синхронизировано, другие потоки не смогут получить статическое поле из SingletonHolder, пока он не будет инициализирован. Рекомендую изучить подробнее порядок инициализации классов в Java, чтобы до конца осознать мудрость этого способа.

Вариант 7

Потокобезопасная реализация с использованием enum. Здесь существование единственного экземпляра обеспечивается самой JVM. Рекомендую узнать подробнее про перечисления в Java.

 

 

 

 

 


Поделиться:

One thought on “Синглетон (одиночка) в Java”

  1. А для чего он нужен, кроме как для того, чтобы про него на собеседованиях спрашивали?

Добавить комментарий

Ваш e-mail не будет опубликован.

*