
Какво е сингълтън в Java?
Singleton е един от най-простите шаблони за проектиране на ниво клас. Понякога хората казват, че „този клас е сингълтън“, което означава, че класът имплементира модела на дизайн сингълтон. Понякога е необходимо да напишем клас, където ограничаваме инстанцията до един обект. Например, клас, отговорен за регистриране or свързване към Единичният модел на дизайн описва How можем да постигнем това. Единичният дизайн е модел, който прави две неща:-
Той гарантира, че винаги ще има само един екземпляр на класа.
-
Той осигурява единна точка за глобален достъп до този екземпляр.
-
Частен строител. Това ограничава възможността за създаване на обекти от класа извън самия клас.
-
Публичен статичен метод, който връща екземпляра на класа. Този метод се нарича getInstance . Това е точката на глобален достъп до екземпляра на класа.
Варианти за изпълнение
Единичният дизайн модел се прилага по различни начини. Всеки вариант е добър и лош по свой начин. Както винаги, тук няма идеален вариант, но трябва да се стремим към такъв. Първо, нека да решим Howво представлява добро и лошо и Howви показатели влияят на начина, по който оценяваме различните реализации на шаблона за проектиране. Да започнем с доброто. Ето факторите, които правят внедряването по-сочно и привлекателно:-
Мързелива инициализация: екземплярът не се създава, докато не е необходим.
-
Прост и прозрачен code: този показател, разбира се, е субективен, но е важен.
-
Безопасност на нишката: правилна работа в многонишкова среда.
-
Висока производителност в многонишкова среда: малко or ниHowво блокиране на нишки при споделяне на ресурс.
-
Без мързелива инициализация: когато класът се зарежда при стартиране на приложението, независимо дали е необходимо or не (парадоксално, в ИТ света е по-добре да си мързелив)
-
Сложен и труден за четене code. Този показател също е субективен. Ако очите ви започнат да кървят, ще приемем, че изпълнението не е най-доброто.
-
Липса на безопасност на резбата. С други думи, "опасност от нишка". Неправилна работа в многонишкова среда.
-
Лоша производителност в многонишкова среда: нишките се блокират взаимно през цялото време or често, когато споделят ресурс.
Код
Сега сме готови да разгледаме различни варианти за внедряване и да посочим плюсовете и минусите:просто
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
Най-простото изпълнение. Професионалисти:
-
Прост и прозрачен code
-
Безопасност на резбата
-
Висока производителност в многонишкова среда
- Без мързелива инициализация.
Мързелива инициализация
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Професионалисти:
-
Мързелива инициализация.
-
Не е безопасно за нишки
Синхронизиран достъп
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Професионалисти:
-
Мързелива инициализация.
-
Безопасност на резбата
-
Лоша многонишкова производителност
Двойно проверено заключване
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Singleton.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
}
}
return INSTANCE;
}
}
Професионалисти:
-
Мързелива инициализация.
-
Безопасност на резбата
-
Висока производителност в многонишкова среда
-
Не се поддържа в по-ранни версии на Java под 1.5 (използването на ключова дума volatile е фиксирано от version 1.5)
Притежател на класа
public class Singleton {
private Singleton() {
}
private static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}
Професионалисти:
-
Мързелива инициализация.
-
Безопасност на резбата.
-
Висока производителност в многонишкова среда.
-
Правилната работа изисква гаранция, че единичният обект е инициализиран без грешки. В противен случай първото извикване на метода getInstance ще доведе до ExceptionInInitializerError и всички следващи извиквания ще произведат NoClassDefFoundError .
Внедряване | Мързелива инициализация | Безопасност на резбата | Многонишкова производителност | Кога да се използва? |
---|---|---|---|---|
просто | - | + | Бърз | Никога. Или евентуално когато мързеливата инициализация не е важна. Но никога не би било по-добре. |
Мързелива инициализация | + | - | Не е приложимо | Винаги, когато многопоточността не е необходима |
Синхронизиран достъп | + | + | Бавен | Никога. Или евентуално когато многонишковата производителност няма meaning. Но никога не би било по-добре. |
Двойно проверено заключване | + | + | Бърз | В редки случаи, когато трябва да обработвате изключения, когато създавате сингълтън (когато притежателят на клас сингълтон не е приложим) |
Притежател на класа | + | + | Бърз | Винаги, когато е необходима многонишковост и има гаранция, че единичният обект ще бъде създаден без проблеми. |
Плюсове и минуси на единичния модел
Като цяло сингълтън прави точно това, което се очаква от него:-
Той гарантира, че винаги ще има само един екземпляр на класа.
-
Той осигурява единна точка за глобален достъп до този екземпляр.
-
Единичният клас нарушава принципа на единичната отговорност: в допълнение към преките си задължения, единичният клас също контролира броя на инстанциите.
-
Зависимостта на обикновен клас от сингълтън не се вижда в публичния договор на класа.
-
Глобалните променливи са лоши. В крайна сметка сингълтън се превръща в голяма глобална променлива.
-
Наличието на сингълтон намалява възможността за тестване на приложението като цяло и в частност на класовете, които използват сингълтона.
GO TO FULL VERSION