1. 程式人生 > 其它 >Singleton——單例模式

Singleton——單例模式

技術標籤:設計模式設計模式單例模式java

Singleton——單例模式

什麼是單例模式

確保一個類只生成一個例項,並提供一個訪問它的全域性訪問點
​ Singleton模式讓類負責儲存它的唯一例項,這個類可以保證沒有其他例項可以被建立,並且提供一個訪問該例項的方法

單例模式的角色構成

  • Singleton
    Singleton角色中有一個返回唯一例項的靜態方法,該方法總會返回同一個例項。

示例程式

類的組成表

類名說明
Singleton只生成一個例項
SingletonMain測試類

示例程式類圖

在這裡插入圖片描述

Singleton類

​ Singleton類只會生成一個例項,Singleton類定義了一個靜態成員變數singleton,在類被載入時會將singleton初始化為Singleton的例項,初始化行為僅在該類被載入時進行一次。

​ Singleton類的建構函式使用了private修飾,這是為了禁止從Singleton類外部呼叫建構函式。如果從Singleton類以外呼叫構造方法new Singleton(),會出現編譯錯誤,getInstance()方法提供了獲取Singleton類唯一例項的入口。

package com.example.singleton;

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
        System.out.
println("生成了一個例項"); } public static Singleton getInstance() { return singleton; } }

SingletonMain類

​ 呼叫兩次getInstance()方法獲取Singleton類的例項,通過"=="判斷是否為同一個例項。

package com.example.singleton;

public class SingletonMain {
    public static void main(String[] args) {
System.out.println("Start"); Singleton obj1 = Singleton.getInstance(); Singleton obj2 = Singleton.getInstance(); if (obj1 == obj2) { System.out.println("obj1和obj2是相同的例項"); } else { System.out.println("obj1和obj2是不同的例項"); } System.out.println("End"); } }

測試結果

Start
生成了一個例項
obj1和obj2是相同的例項
End

拓展延伸

多執行緒下的單例模式

在多執行緒環境下,以下程式在多個執行緒呼叫getInstance()方法建立例項時,可能會生成多個例項;

示例程式:
SingletonThread類
package com.example.singleton.test;

public class SingletonThread {
    private static SingletonThread singleton = null;

    private SingletonThread() {
        System.out.println("生成了一個例項");
        slowdown();
    }

    public static SingletonThread getInstance() {
        // 執行緒不安全,使用null == singleton判斷例項為空後,生成了一個新的例項
        // 在多執行緒環境下,其他執行緒也可能判斷 if (null == singleton)
        if (null == singleton) {
            singleton = new SingletonThread();
        }
        return singleton;
    }


    private void slowdown() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

SingletonThreadMain類

package com.example.singleton.test;

public class SingletonThreadMain extends Thread{
    public static void main(String[] args) {
        System.out.println("Start.");
        new SingletonThreadMain("A").start();
        new SingletonThreadMain("B").start();
        new SingletonThreadMain("C").start();
        System.out.println("End.");
    }

    public void run() {
        SingletonThread obj = SingletonThread.getInstance();
        System.out.println(getName() + ": obj = " + obj);
    }

    public SingletonThreadMain(String name) {
        super(name);
    }
}
測試結果
Start.
End.
生成了一個例項
生成了一個例項
生成了一個例項
B: obj = [email protected]
C: obj = [email protected]
A: obj = [email protected]

[email protected]
C: obj = [email protected]
A: obj = [email protected]