單例模式
模式動機
單例模式(Singleton Pattern)是結構最簡單的設計模式,它的核心結構中只包含一個被稱為單例類的特殊類,通過單例模式可以確保系統中一個類只有一個實體,且該實體易于被外界訪問,從而方便對實體個數的控制并節約系統資源,
- 定義一個全域變數可以確保物件隨時都可以被訪問,但是不能防止實體化多個物件,(代碼實作)
- 更好的辦法是讓類自身負責創建和保存它的唯一實體,并保證不能創建其他實體,并且提供一個訪問該實體的方法,(機制實作)
模式定義
- 單例模式(Singleton Pattern):確保某一個類只有一個實體,而且自行實體化并向整個系統提供這個實體,這個類稱為單例類,它提供全域訪問的方法,
- 單例模式的要點有三個:
- 某個類只能有一個實體
- 必須自行創建這個實體
- 必須自行向整個系統提供這個實體
- 單例模式是一種物件創建型模式
模式結構

模式分析
- 私有建構式
- 靜態私有成員變數(自身型別)
- 靜態公有的工廠方法
單例類:
public class Singleton {
//靜態私有成員變數
private static Singleton instance=null;
//私有建構式
private Singleton() {
}
//靜態公有工廠方法,回傳唯一實體
public static Singleton getInstance() {
if(instance==null)
instance=new Singleton();
return instance;
}
}
-
單例模式的目的
- 保證一個類只有一個唯一的實體,并為它提供一個全域訪問點,
-
實作單例模式的思想
- 為了防止客戶端程式使用建構式來創建多個物件,可以將建構式宣告為私有的,這樣客戶端程式就不可以使用它來創建任何物件,
-
單例模式的問題
- 如果宣告建構式為私有型別,那么沒有客戶端程式可以使用它來創建任何物件,因此它對客戶端程式是無用的,
-
單例模式優點
- 提供了對唯一實體的受控訪問
- 可以節約系統資源,提高系統的性能
- 允許可變數目的實體(多例類)
-
單例模式缺點
- 擴展困難(缺少抽象層)
- 單例類的職責過重,單例模式與單一職責原則有沖突,一個類應該只實作一個邏輯,而不關心它是否是單例的,是不是要單例取決于環境,單例模式把“要單例”和業務邏輯融合在一個類中
- 由于自動垃圾回識訓制,可能會導致共享的單例物件的狀態丟失
-
在以下情況下可以使用單例模式
- 系統只需要一個實體物件,或者因為資源消耗太大而只允許創建一個物件
- 客戶呼叫類的單個實體只允許使用一個公共訪問點,除了該公共訪問點,不能通過其他途徑訪問該實體
單例模式分類
餓漢式(Eager Singleton):顧名思義,該模式在類被加載時就會實體化一個物件,
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() { }
public static EagerSingleton getInstance() {
return instance;
}
}
懶漢式(Lazy Singlenton):該模式只在你需要物件時才會生成單例物件(比如呼叫getInstance方法)
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() { }
public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
關于Synchronized 型別的方法
- Synchronized型別的方法限制每個執行此方法的執行緒必須在執行下一個執行緒之前完全執行;
- 通過這種方式,創建的物件在多個執行緒的情況下是唯一的;
- 也就是說,我們已經給Synchronized型別的物件添加了鎖,當一個執行緒執行此方法時,其他方法無法接管,其他執行緒應該等待.
- 只有在當前執行緒執行完該方法后,另一個執行緒才能開始執行該方法
鎖方法:
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() { }
synchronized public static LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
鎖代碼段
public static LazySingleton getInstance() {
if (instance == null) {
synchronized (LazySingleton.class) {
instance = new LazySingleton();
}
}
return instance;
}
懶漢式與餓漢式比較
| 懶漢式 | 餓漢式 | |
|---|---|---|
| 實體化 | 外部呼叫時 | 類加載時 |
| 執行緒安全 | 不安全 | 安全 |
| 執行效率 | 較低 | 較高 |
| 記憶體 | 不浪費 | 浪費 |
本文來自博客園,作者:街酒,轉載請注明原文鏈接:https://www.cnblogs.com/sorrymine/p/17384211.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/552048.html
標籤:其他
下一篇:返回列表
