Singleton——單例模式
阿新 • • 發佈:2021-02-20
Singleton——單例模式
什麼是單例模式
確保一個類只生成一個例項,並提供一個訪問它的全域性訪問點。
Singleton模式讓類負責儲存它的唯一例項,這個類可以保證沒有其他例項可以被建立,並且提供一個訪問該例項的方法
單例模式的角色構成
- Singleton
Singleton角色中有一個返回唯一例項的靜態方法,該方法總會返回同一個例項。
示例程式
類的組成表
類名 | 說明 |
---|---|
Singleton | 只生成一個例項 |
SingletonMain | 測試類 |
示例程式類圖
Singleton類
Singleton類只會生成一個例項,Singleton類定義了一個靜態成員變數singleton,在類被載入時會將singleton初始化為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]