Werfen wir zunächst einen Blick auf die Definition des Singleton-Musters:
Das Singleton-Muster ist eines der einfachsten Entwurfsmuster in Java und ein Erstellungsmuster. Es bietet die beste Möglichkeit, Objekte zu erstellen. Das Singleton-Muster umfasst eine einzelne Klasse, die für die Erstellung ihrer eigenen Objekte verantwortlich ist und gleichzeitig sicherstellt, dass nur ein einziges Objekt erstellt wird.
(Empfohlenes Tutorial: Java Getting Started Tutorial)
Um sicherzustellen, dass sich nur ein Objekt im Speicher befindet und die häufige Erstellung von Objekten vermieden wird, die Speicher verbrauchen, verwenden Sie diesen Singleton überall dort, wo Sie dieses Objekt aufrufen müssen .
Als nächstes werfen wir einen Blick auf die Arten von Singleton-Mustern:
1 Lazy-Stil
Lazy-Stil bedeutet, dass das Singleton-Objekt nur dann erstellt wird, wenn es benötigt wird.
Lazy-Style-Singleton-Musterimplementierung:
public class Singleton { private static Singleton singleton; private Singleton(){ } public static Singleton getInstance(){ if (singleton == null) { singleton = new Singleton(); } return singleton; }
Es gibt ein Problem mit der Lazy-Style-Singleton-Implementierung, das heißt, wie kann sichergestellt werden, dass nur ein Objekt erstellt wird? Wenn zwei oder mehr Threads gleichzeitig feststellen, dass Singleton leer ist, werden mehrere Objekte erstellt. Daher müssen wir das Thread-Sicherheitsproblem lösen.
Wenn es um Thread-Sicherheit geht, fällt mir beim Sperren nichts anderes ein als das Sperren von Methoden oder Klassenobjekten.
//在方法上加锁 public class Singleton { private static Singleton singleton; private Singleton(){} public static synchronized Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } } //在类对象上加锁 public class Singleton { private static Singleton singleton; private Singleton(){} public static Singleton getInstance() { synchronized(Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } return singleton; } }
Diese beiden Methoden können das Problem lösen, dass Multithreads gleichzeitig Singleton-Objekte erstellen, aber jedes Mal, wenn Sie das Objekt erhalten, müssen Sie zuerst die Sperre erwerben, und die Parallelitätsleistung ist schlecht. Daher ist weiterhin eine Optimierung erforderlich: Wenn kein instanziiertes Objekt vorhanden ist, sperren und erstellen Sie es. Wenn es ein instanziiertes Objekt gibt, kehren Sie direkt zurück.
(Lernvideo-Empfehlung: Java-Kurs)
Für das Sperren einer Methode ist das Sperren erforderlich, unabhängig davon, ob ein instanziiertes Objekt vorhanden ist. Daher müssen wir optimieren, indem wir das Klassenobjekt sperren.
//DCL单例模式(Double Check + Lock) public class Singleton { //volatite关键词防止指令重排序,下文介绍 private static volatile Singleton singleton; private Singleton(){} public static Singleton getInstance() { //如果singleton不为空,则直接返回对象,若多个线程发现singleton为空,则进入分支 if (singleton == null) { //多个线程同时争抢一个锁,只有一个线程能成功,其他线程需等待 synchronized(Singleton.class) { //争抢到锁的线程需再次判断singleton是否为空,因为有可能被上个线程实例化了 //若不为空则实例化,后续线程再进入的时候则直接返回该对象 //对于之后所有进入该方法的线程则无需获取锁,直接返回对象 if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
Das Schlüsselwort volatile wird zum obigen Code hinzugefügt, um eine Neuordnung der Anweisungen zu verhindern.
2. Hungriger chinesischer Stil
Hungriger chinesischer Stil bedeutet, dass das Singleton-Objekt erstellt wird, wenn die Klasse geladen wird.
Hungry-Singleton-Musterimplementierung:
public class Singleton { private static final Singleton singleton = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return singleton; }
Zusammenfassung:
Lazy-Man-Stil: Instanziieren Sie Objekte nur bei Bedarf, wenn der Speicherbedarf hoch ist. In einer Multithread-Umgebung Sollte den DCL-Singleton-Modus verwenden, löst die Verwendung des DCL-Singleton-Modus die Probleme der Parallelitätssicherheit und der geringen Leistung. Wenn das Schlüsselwort volatile hinzugefügt wird, kann es auch NPE-Ausnahmen verhindern, die durch die Neuordnung von Befehlen verursacht werden.
Hungry Chinese-Stil: Das Objekt wurde beim Laden der Klasse bereits instanziiert. Wenn der Speicherbedarf nicht hoch ist, verwenden Sie den Hungry Chinese-Stil. Er ist einfach, nicht fehleranfällig und bietet keine Parallelitätssicherheit und Leistung Probleme.
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in das Singleton-Muster. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!