Das Singleton-Muster weist die folgenden Merkmale auf:
1. Eine Singleton-Klasse kann nur eine Instanz haben.
2. Eine Singleton-Klasse muss ihre eigene eindeutige Instanz erstellen.
3. Die Singleton-Klasse muss diese Instanz allen anderen Objekten bereitstellen.
Das Singleton-Muster stellt sicher, dass es nur eine Instanz einer Klasse gibt, instanziiert sich selbst und stellt diese Instanz dem gesamten System zur Verfügung. In Computersystemen werden Thread-Pools, Caches, Protokollobjekte, Dialogfelder, Drucker und Grafikkartentreiberobjekte häufig als Singletons konzipiert. Diese Anwendungen verfügen alle mehr oder weniger über die Funktionalität von Ressourcenmanagern. Jeder Computer kann über mehrere Drucker verfügen, es kann jedoch nur ein Druckerspooler vorhanden sein, um zu verhindern, dass zwei Druckaufträge gleichzeitig auf dem Drucker ausgegeben werden. Jeder Computer kann über mehrere Kommunikationsanschlüsse verfügen. Das System sollte diese Kommunikationsanschlüsse zentral verwalten, um zu verhindern, dass ein Kommunikationsanschluss gleichzeitig von zwei Anforderungen aufgerufen wird. Kurz gesagt besteht der Zweck der Wahl des Singleton-Modus darin, inkonsistente Zustände und langfristige Richtlinien zu vermeiden.
Schauen wir uns zunächst eine klassische Singleton-Implementierung an.
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse Singleton {
private static Singleton uniqueInstance = null;
privater Singleton() {
// Existiert nur, um die Instanziierung zu verhindern.
}
public static Singleton getInstance() { if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Andere Methoden...
}
Singleton verhindert, dass die Klasse extern instanziiert wird, indem die Konstruktionsmethode auf privat beschränkt wird. Innerhalb derselben virtuellen Maschine kann auf die einzige Instanz von Singleton nur über die Methode getInstance() zugegriffen werden. (Tatsächlich ist es möglich, eine Klasse mit einem privaten Konstruktor über den Java-Reflexionsmechanismus zu instanziieren, wodurch grundsätzlich alle Java-Singleton-Implementierungen ungültig werden. Dieses Problem wird hier nicht besprochen. Nehmen wir an, dass der Reflexionsmechanismus nicht existiert. .)
Die obige Implementierung berücksichtigt jedoch keine Thread-Sicherheitsprobleme. Die sogenannte Thread-Sicherheit bedeutet: Wenn in dem Prozess, in dem sich Ihr Code befindet, mehrere Threads gleichzeitig laufen, können diese Threads diesen Code gleichzeitig ausführen. Wenn die Ergebnisse jedes Laufs mit denen von Single-Thread-Läufen übereinstimmen und die Werte anderer Variablen mit den Erwartungen übereinstimmen, ist dies Thread-sicher. Mit anderen Worten: Die von einer Klasse oder einem Programm bereitgestellte Schnittstelle ist eine atomare Operation für Threads oder das Umschalten zwischen mehreren Threads führt nicht zu Mehrdeutigkeiten in den Ausführungsergebnissen der Schnittstelle, was bedeutet, dass wir keine Synchronisationsprobleme berücksichtigen müssen. Offensichtlich erfüllt die obige Implementierung nicht die Anforderungen der Thread-Sicherheit, und es ist wahrscheinlich, dass mehrere Singleton-Instanzen in einer gleichzeitigen Umgebung angezeigt werden.
Kopieren Sie den Codecode wie folgt:
//Singleton-Klasse im hungrigen Stil. Sie wurde bei der Initialisierung der Klasse selbst instanziiert.
öffentliche Klasse Singleton1 {
//Privater Standardkonstruktor
private Singleton1() {}
//Bereits von selbst instanziiert
private static final Singleton1 single = new Singleton1();
//statische Factory-Methode
öffentliches statisches Singleton1 getInstance() {
Single zurückgeben;
}
}
//Lazy Singleton-Klasse. Beim ersten Aufruf instanziieren
öffentliche Klasse Singleton2 {
//Privater Standardkonstruktor
private Singleton2() {}
//Beachten Sie, dass es hier kein Finale gibt
private static Singleton2 single=null;
//statische Factory-Methode
öffentliches synchronisiertes statisches Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
Single zurückgeben;
}
}