Назначение
Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
Использование шаблона в JDK
(примеры частично взяты с этого ресурса)
Вариации
"Эталонная" реализация (Lazy Singleton):
1. public class SomeClass {
2. private static SomeClass instance = null;
3. private SomeClass() {}
4. public static synchronized SomeClass getInstance() {
5. if (instance == null) {
6. instance = new SomeClass();
7. }
8. return instance;
9. }
10.}
Вопросы:
- можно ли в строке 1 поставить public final class?
- можно ли в строке 2 убрать static?
- можно ли в строке 3 убрать private?
- можно ли в строке 4 убрать synchronized?
- можно ли в строке 4 убрать static?
- можно ли убрать static одновременно в строках 2 и 4?
- можно ли убрать строки 5 и 7 (проверка)?
- что будет, если вызов конструктора в строке 6 бросит исключение (заменим строку 3 на private SomeClass() {throw new RuntimeException();})? Что произойдет при последующем вызове getInstance()? Каково значение поля instance?
- можно ли в строке 4 написать static final synchronized?
"Ранняя" загрузка (Early Singleton):
1. class SomeClass {
2. private static SomeClass instance = new SomeClass();
3. private SomeClass() {}
4. public static SomeClass getInstance() {
5. return instance;
6. }
7.}
Вопросы:
- можно ли в строке 4 добавить synchronized?
- что будет, если вызов конструктора в строке 2 бросит исключение (заменим строку 3 на private SomeClass() {throw new RuntimeException();})? Что произойдет при последующем вызове getInstance()? Каково значение поля instance?
Множественная загрузка синглетона
В один сервлет-контейнер (Tomcat) можно задеплоить много раз один и тот же war (под разными context path). Предположим, что в war лежит синглетон.
Вопрос:
- каким образом у разных war - разные синглетоны, если все war запущены в одной JVM? (почитайте про ClassLoader-ы)
- Есть ли возможность в Tomcat сделать синглетон, разделяемый различными war-ами? (почитайте про папку ??? в Tomcat)
"Скрытый" синглетон
Хотя есть возможность создавать много объектов данного типа, они все разделяют "одно состояние" (или "часть состояния" - не все поля статические).
1. class SomeClass {
2. private static int counter;
3. public SomeClass() {}
4. public synchronized void increment() {
5. counter++;
6. }
7. public synchronized int getCounter() {
8. return counter;
9. }
10.}
В данном случае, все объекты типа SomeClass разделяют общий counter. Может использоваться для сокрытия от пользователя того, что используется совместное состояние. Частая форма реализации кэшей.
Пример: возможный кэш для PreparedStatement в JDBC driver.
Пример: возможный кэш для ??? в JDBC driver.
Пример: возможный кэш для ??? в JDBC driver.
Пример: кэш первого уровня у Hibernate.
Пример: кэш второго уровня у Hibernate.
Конкурирующие потоки и синглетон
Синглетон и TDD
Multiton
Пример с enum
Double-Checked Locking idiom
Статья "The Double-Checked Locking is Broken Declaration"
Порядок конструирования синглетонов
Деструкция синглетона
Порядок деструкции синглетонов
Синглетоны в Servlet API
Синглетоны в JDBC
Синглетоны в IoC/DI-контейнерах (Spring, Guice)
Синглетоны в Servlet API
Синглетоны в OSGi
Гарантирует, что у класса есть только один экземпляр, и предоставляет к нему глобальную точку доступа.
Использование шаблона в JDK
(примеры частично взяты с этого ресурса)
Вариации
"Эталонная" реализация (Lazy Singleton):
1. public class SomeClass {
2. private static SomeClass instance = null;
3. private SomeClass() {}
4. public static synchronized SomeClass getInstance() {
5. if (instance == null) {
6. instance = new SomeClass();
7. }
8. return instance;
9. }
10.}
Вопросы:
- можно ли в строке 1 поставить public final class?
- можно ли в строке 2 убрать static?
- можно ли в строке 3 убрать private?
- можно ли в строке 4 убрать synchronized?
- можно ли в строке 4 убрать static?
- можно ли убрать static одновременно в строках 2 и 4?
- можно ли убрать строки 5 и 7 (проверка)?
- что будет, если вызов конструктора в строке 6 бросит исключение (заменим строку 3 на private SomeClass() {throw new RuntimeException();})? Что произойдет при последующем вызове getInstance()? Каково значение поля instance?
- можно ли в строке 4 написать static final synchronized?
"Ранняя" загрузка (Early Singleton):
1. class SomeClass {
2. private static SomeClass instance = new SomeClass();
3. private SomeClass() {}
4. public static SomeClass getInstance() {
5. return instance;
6. }
7.}
Вопросы:
- можно ли в строке 4 добавить synchronized?
- что будет, если вызов конструктора в строке 2 бросит исключение (заменим строку 3 на private SomeClass() {throw new RuntimeException();})? Что произойдет при последующем вызове getInstance()? Каково значение поля instance?
Множественная загрузка синглетона
В один сервлет-контейнер (Tomcat) можно задеплоить много раз один и тот же war (под разными context path). Предположим, что в war лежит синглетон.
Вопрос:
- каким образом у разных war - разные синглетоны, если все war запущены в одной JVM? (почитайте про ClassLoader-ы)
- Есть ли возможность в Tomcat сделать синглетон, разделяемый различными war-ами? (почитайте про папку ??? в Tomcat)
"Скрытый" синглетон
Хотя есть возможность создавать много объектов данного типа, они все разделяют "одно состояние" (или "часть состояния" - не все поля статические).
1. class SomeClass {
2. private static int counter;
3. public SomeClass() {}
4. public synchronized void increment() {
5. counter++;
6. }
7. public synchronized int getCounter() {
8. return counter;
9. }
10.}
В данном случае, все объекты типа SomeClass разделяют общий counter. Может использоваться для сокрытия от пользователя того, что используется совместное состояние. Частая форма реализации кэшей.
Пример: возможный кэш для PreparedStatement в JDBC driver.
Пример: возможный кэш для ??? в JDBC driver.
Пример: возможный кэш для ??? в JDBC driver.
Пример: кэш первого уровня у Hibernate.
Пример: кэш второго уровня у Hibernate.
Конкурирующие потоки и синглетон
Синглетон и TDD
Multiton
Пример с enum
Double-Checked Locking idiom
Статья "The Double-Checked Locking is Broken Declaration"
Порядок конструирования синглетонов
Деструкция синглетона
Порядок деструкции синглетонов
Синглетоны в Servlet API
Синглетоны в JDBC
Синглетоны в IoC/DI-контейнерах (Spring, Guice)
Синглетоны в Servlet API
Синглетоны в OSGi