Heim  >  Artikel  >  Java  >  Beherrschen Sie das Java-Singleton-Muster vollständig

Beherrschen Sie das Java-Singleton-Muster vollständig

WBOY
WBOYnach vorne
2022-04-13 19:04:081838Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über Java und stellt hauptsächlich verwandte Probleme zum Singleton-Modus vor, der sich auf einen Modus bezieht, in dem eine Klasse nur eine Instanz hat und die Klasse diese Instanz wie folgt selbst erstellen kann Schauen Sie es sich gemeinsam an. Ich hoffe, es wird für alle hilfreich sein.

Beherrschen Sie das Java-Singleton-Muster vollständig

Empfohlenes Lernen: „Java-Video-Tutorial

Einzelfallmuster:

Zuallererst gibt es in Java 23 Designmuster:

  • Kreatives Muster : Fabrik Methodenmuster, abstraktes Fabrikmuster, Singleton-Muster, Builder-Muster, Prototypmuster
  • Strukturmuster: Adaptermuster, Dekoratormuster, Proxy-Muster, Erscheinungsmuster, Brückenmuster, Kompositionsmuster, Fliegengewichtsmuster
  • Verhalten Typmuster: : Strategiemuster, Vorlagenmethodenmuster, Beobachtermuster, Iteratormuster, Verantwortungskettenmuster, Befehlsmuster, Memomuster, Zustandsmuster, Besuchermuster, Vermittlermuster, Interpretermuster.

1. Was ist das Singleton-Muster:

Definition:
bezieht sich auf ein Muster, in dem eine Klasse nur eine Instanz hat und die Klasse diese Instanz selbst erstellen kann. Dadurch kann die Verschwendung von Speicherressourcen durch das Öffnen mehrerer Task-Manager-Fenster oder Fehler wie inkonsistente Anzeigeinhalte in jedem Fenster vermieden werden. Kann auf unserem Computer beispielsweise nur ein Task-Manager geöffnet sein? Richtig, das dient der Vermeidung von Ressourcenverschwendung und anderen Fehlern.

In Projekten können Sie im Allgemeinen den Singleton-Modus verwenden, um dasselbe Objekt zum Aufrufen von Tool-Methoden zu erhalten. Der Vorteil besteht darin, dass ich nicht mehrere verschiedene Objekte erstellen muss, da dies Speicherressourcen verbraucht

Kurz gesagt:

Ein Singleton bedeutet, dass das Programm nur eine Instanz hat. Diese Klasse ist für die Erstellung eines eigenen Objekts verantwortlich. Gleichzeitig muss sichergestellt werden, dass nur eine Objekterstellung erfolgt Funktionen des Singletons Muster:

Konstruktor privat

    Enthält seine eigenen Typattribute
  1. stellt externe statische Methoden zum Abrufen von Instanzen bereit
  2. Strukturdiagramm des Singleton-Modus:


Beherrschen Sie das Java-Singleton-Muster vollständig 2. Vor- und Nachteile des Singleton-Modus:

Vorteile:

Reduzierter Speichernutzungs-Overhead

    Mehrfachbelegung von Ressourcen vermeiden
  1. Einen globalen Zugangspunkt einrichten, um den Zugriff auf Ressourcen zu optimieren und zu teilen
  2. Nachteile (aus dem Internet referenziert):

Im Allgemeinen gibt es keine Schnittstelle und die Erweiterung ist schwierig. Wenn Sie erweitern möchten, gibt es keine andere Möglichkeit, als den Originalcode zu ändern, was gegen das Öffnungs- und Schließprinzip verstößt

    Bei gleichzeitigen Tests ist der Singleton-Modus für das Code-Debuggen nicht förderlich. Wenn der Code im Singleton während des Debugging-Prozesses nicht ausgeführt wurde, kann der Funktionscode des Singleton-Modus normalerweise nicht in einer Klasse geschrieben werden Einzelverantwortung. Prinzipien
  1. Sehen Sie sich eine Mindmap des Singleton-Modus an:

3. Lazy-Modus (häufiger verwendet)

Das Merkmal des Lazy-Modus ist die verzögerte Initialisierung und das Objekt wird nicht instanziiert Bis die Methode aufgerufen wird, um die Instanz abzurufen.

Thread ist nicht sicher, streng genommen handelt es sich nicht um einen Singleton-Modus. Der Vorteil besteht darin, dass das Objekt nach dem Abrufen der Instanz erstellt wird, sodass Speicheraufwand gespart wird
public class SingLeton {

    //1、有自己类型的属性
    private static SingLeton instance;

    //2、构造器私有化
    private SingLeton(){}

    //3、对外提供获取实例的静态方法
    public static SingLeton getInstance(){
        if (instance == null){
            instance = new SingLeton();
        }
        return instance;
    }}

Testklasse:


public class Test {
    public static void main(String[] args) {

        //判断是否产生的是同一个对象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}

Ausgabe:

true

Hinweis:

Über Lazy-Mode-Threads ist nicht sicher

Jetzt wissen wir, dass Lazy-Mode-Threads nicht sicher sind sicher, also müssen Sie es tun Verwenden Sie Sperren (synchronisiert), um zu synchronisieren:

/**
 *   保证 instance 在所有线程中同步
 */public class SingLeton2 {

        //1、有自己类型的属性
        private static volatile SingLeton2 instance ;    
        
        //2、构造器私有化
        private SingLeton2() {
        }

        public static synchronized SingLeton2 getInstance() {
            //getInstance 方法前加同步
            if (instance == null) {
                instance = new SingLeton2();
            }
            return instance;
        }
    }
Wenn Sie mehrere Threads schreiben, löschen Sie nicht die Schlüsselwörter volatile und synchronisiert im obigen Beispielcode, da sonst Thread-Sicherheitsprobleme auftreten. Wenn Sie diese beiden Schlüsselwörter nicht löschen, können Sie die Thread-Sicherheit gewährleisten. Bei jedem Zugriff ist jedoch eine Synchronisierung erforderlich, was sich auf die Leistung auswirkt und mehr Ressourcen verbraucht.

4. Der Hungry Han-Modus [Empfohlen]

Der Hungry Han-Modus ist threadsicher und wird häufig verwendet, aber es ist einfach, Müllobjekte zu generieren, da der Hungry Han-Modus

Instanzen initialisiert, wenn er zum ersten Mal eine Klasse lädt

Demo:

/**
 *
 * 饿汉模式
 */public class SingLeton {

    //持有自己类型的属性   (和懒汉一样)
    //由于static修饰,只在类加载的时候执行一次,类加载的时候就实例化对象
    private static SingLeton instance = new SingLeton();

    //构造器私有化,不能通过它创建对象
    private SingLeton(){};

    //对外提供获取实例的静态方法
    public static SingLeton getInstance(){
        return instance;
    }}

Testklasse:

public class Test {
    public static void main(String[] args) {

        //判断是否产生的是同一个对象
        SingLeton s1 = SingLeton.getInstance();
        SingLeton s2 = SingLeton.getInstance();
        System.out.println(s1 == s2);
    }}


Ausgabe:

true
Vergleich zwischen Lazy-Modus und Hungrig-Modus:

  1. 懒汉模式延迟加载,非线程安全,饿汉模式线程安全
  2. 懒汉模式刚运行不实例化对象,需要的时候才实例化对象,相当于来讲更节省内存开销
  3. 饿汉模式只要运行都会加载类的时候就给你初始化了,就需要使用更大的内存

图解:
Beherrschen Sie das Java-Singleton-Muster vollständig

5、单例模式的应用场景:

  1. 需要经常创建的一些类,使用单例可以降低系统的内存压力
  2. 这个类只要求生成一个对象的时候,比如每个人的名字
  3. 类创建实例时占用资源较多,或实例化耗时较长,且经常使用
  4. 频繁访问数据库或文件的对象
  5. 类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池

6、单例模式的应用实例

这里使用懒汉式单例模式模拟产生班级的班长
分析: 在每一个学期内,班级的班长只有一人,所以适合用单例模式实现

Person类:

/**
 * 使用懒汉模式
 */public class Person {

    //保证instance在所有线程中同步
    private static volatile Person instance;

    private Person(){
        System.out.println("产生一个班长");
    }

    //加上synchronized锁
    public static synchronized Person getInstance(){
        if(instance == null){
            instance = new Person();
        }else {
            System.out.println("错误信息:已经有一个班长,不能再产生");
        }
        return instance;
    }

    public void getName(){
        System.out.println("我是班长:小强");
    }}

测试类:

public class Test {
    public static void main(String[] args) {

        Person p1 = Person.getInstance();
        p1.getName(); //输出班长名字

        Person p2 = Person.getInstance();
        p2.getName();

        if(p1 == p2){
            System.out.println("两个班长是同一个人");
        }else {
            System.out.println("两个班长是同一个人");

        }
    }}

运行结果:

产生一个班长
我是班长:小强
错误信息:已经有一个班长,不能再产生
我是班长:小强
两个班长是同一个人

小结:

这个就是单例模式,当程序已经产生一个对象后,就不会产生一个新的对象,即使有多个对象也是同一个对象而已,在使用懒汉模式的时候需要注意线程安全问题,在平时更加推荐使用饿汉模式,也需要注意资源的占用。

推荐学习:《java教程

Das obige ist der detaillierte Inhalt vonBeherrschen Sie das Java-Singleton-Muster vollständig. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen