
Mi az a szingli a Java nyelven?
A Singleton az egyik legegyszerűbb osztályszintű tervezési minta. Néha az emberek azt mondják, hogy "ez az osztály egyszemélyes", ami azt jelenti, hogy az osztály megvalósítja az egytagú tervezési mintát. Néha olyan osztályt kell írni, ahol a példányosítást egyetlen objektumra korlátozzuk. Például egy osztály, amely a naplózásért vagy a csatlakozásért felelős adatbázis. A singleton tervezési minta leírja, hogyan érhetjük el ezt. A singleton olyan tervezési minta, amely két dolgot tesz:-
Garantálja, hogy az osztálynak csak egy példánya lesz.
-
Egyetlen globális hozzáférési pontot biztosít az adott példányhoz.
-
Egy magán kivitelező. Ez korlátozza az osztály objektumok létrehozásának lehetőségét magán az osztályon kívül.
-
Nyilvános statikus metódus, amely visszaadja az osztály példányát. Ezt a módszert getInstance-nak hívják . Ez az osztálypéldány globális elérési pontja.
Megvalósítási lehetőségek
A singleton tervezési mintát többféleképpen alkalmazzák. Mindegyik lehetőség jó és rossz a maga módján. Mint mindig, itt sem létezik tökéletes lehetőség, de törekednünk kell egy ilyenre. Először is döntsük el, hogy mi számít jónak és rossznak, és milyen mérőszámok befolyásolják a tervezési minta különböző megvalósításainak értékelését. Kezdjük a jóval. Íme olyan tényezők, amelyek szaftosabbá és vonzóbbá teszik a megvalósítást:-
Lusta inicializálás: a példány nem jön létre, amíg nincs rá szükség.
-
Egyszerű és átlátható kód: ez a mérőszám természetesen szubjektív, de fontos.
-
Menetbiztonság: megfelelő működés többszálas környezetben.
-
Nagy teljesítmény többszálú környezetben: kevés vagy semmilyen szálblokkolás erőforrás megosztása során.
-
Nincs lusta inicializálás: amikor az osztály betöltődik az alkalmazás indulásakor, függetlenül attól, hogy szükség van-e rá (paradox módon az IT világban jobb lustának lenni)
-
Összetett és nehezen olvasható kód. Ez a mérőszám is szubjektív. Ha a szeme elkezd vérezni, feltételezzük, hogy a megvalósítás nem a legjobb.
-
A menetbiztonság hiánya. Más szóval "szálveszély". Helytelen működés többszálú környezetben.
-
Gyenge teljesítmény többszálú környezetben: a szálak mindig vagy gyakran blokkolják egymást, amikor megosztanak egy erőforrást.
Kód
Most készen állunk arra, hogy megvizsgáljuk a különböző megvalósítási lehetőségeket, és jelezzük az előnyöket és hátrányokat:Egyszerű
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}
A legegyszerűbb megvalósítás. Előnyök:
-
Egyszerű és átlátható kód
-
Menetbiztonság
-
Nagy teljesítmény többszálú környezetben
- Nincs lusta inicializálás.
Lusta inicializálás
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {}
public static Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Előnyök:
-
Lusta inicializálás.
-
Nem cérnabiztos
Szinkronizált hozzáférés
public class Singleton {
private static final Singleton INSTANCE;
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (INSTANCE == null) {
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
Előnyök:
-
Lusta inicializálás.
-
Menetbiztonság
-
Gyenge többszálú teljesítmény
Duplán ellenőrzött zár
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;
}
}
Előnyök:
-
Lusta inicializálás.
-
Menetbiztonság
-
Nagy teljesítmény többszálú környezetben
-
A Java korábbi, 1.5 alatti verziói nem támogatják (a volatile kulcsszó használata az 1.5-ös verzió óta rögzített)
Osztálytartó
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;
}
}
Előnyök:
-
Lusta inicializálás.
-
Menetbiztonság.
-
Nagy teljesítmény többszálú környezetben.
-
A helyes működéshez garantálni kell, hogy a singleton objektum hibamentesen inicializálódik. Ellenkező esetben a getInstance metódus első hívása ExceptionInInitializerError hibát eredményez , és minden további hívás NoClassDefFoundError hibát eredményez .
Végrehajtás | Lusta inicializálás | Menetbiztonság | Többszálú teljesítmény | Mikor kell használni? |
---|---|---|---|---|
Egyszerű | - | + | Gyors | Soha. Vagy esetleg amikor a lusta inicializálás nem fontos. De soha nem lenne jobb. |
Lusta inicializálás | + | - | Nem alkalmazható | Mindig, ha nincs szükség többszálra |
Szinkronizált hozzáférés | + | + | Lassú | Soha. Vagy esetleg amikor a többszálú teljesítmény nem számít. De soha nem lenne jobb. |
Duplán ellenőrzött zár | + | + | Gyors | Ritka esetekben, amikor kivételeket kell kezelnie a szingli létrehozásakor (amikor az osztálytartó szingli nem alkalmazható) |
Osztálytartó | + | + | Gyors | Amikor többszálra van szükség, és garantált, hogy a singleton objektum problémamentesen jön létre. |
A singleton minta előnyei és hátrányai
Általánosságban elmondható, hogy egy szingli pontosan azt teljesíti, amit elvárnak tőle:-
Garantálja, hogy az osztálynak csak egy példánya lesz.
-
Egyetlen globális hozzáférési pontot biztosít az adott példányhoz.
-
Az egyszemélyes osztály sérti az egyetlen felelősség elvét: a szingli osztály a közvetlen feladatai mellett az esetek számát is szabályozza.
-
Egy közönséges osztály szinglitől való függése nem látható az osztály közbeszerzési szerződésében.
-
A globális változók rosszak. Végső soron egy szingli egy hatalmas globális változóvá válik.
-
Az egyszó jelenléte csökkenti az alkalmazás egészének tesztelhetőségét, és különösen a szinglitonust használó osztályok tesztelhetőségét.
GO TO FULL VERSION