設計模式-單例模式
單例模式(Singleton Pattern)解釋
定義
單例模式是一種創建型設計模式,確保一個類只有一個實例,并提供一個全局訪問點來獲取它。
單例模式的特點
- 全局唯一性:單例類只能有一個實例。
- 全局訪問點:通過提供一個靜態方法或屬性,允許其他類訪問該唯一實例。
- 懶加載:實例在第一次使用時創建,避免不必要的資源消耗(可選)。
單例模式的實現方式
以下用 Java 示例講解常見的單例模式實現方式。
1. 餓漢式(Eager Initialization)
在類加載時就創建實例,線程安全,但如果實例未被使用會浪費資源。
public class Singleton {
// 靜態實例,類加載時初始化
private static final Singleton INSTANCE = new Singleton();
// 私有構造方法,防止外部實例化
private Singleton() {}
// 提供全局訪問點
public static Singleton getInstance() {
return INSTANCE;
}
}
優點:實現簡單,線程安全。
缺點:類加載時就創建實例,即使未使用也會占用資源。
2. 懶漢式(Lazy Initialization)
在需要時才創建實例,線程不安全。
public class Singleton {
private static Singleton instance;
// 私有構造方法
private Singleton() {}
// 提供全局訪問點
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
優點:實例在第一次使用時創建,避免資源浪費。
缺點:多線程環境下可能導致線程安全問題。
3. 線程安全的懶漢式
通過 synchronized 關鍵字解決線程安全問題。
public class Singleton {
private static Singleton instance;
private Singleton() {}
// 提供線程安全的全局訪問點
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
優點:線程安全,懶加載。
缺點:性能較低,每次獲取實例時都需要同步。
4. 雙重檢查鎖(Double-Checked Locking)
結合懶加載和線程安全,推薦使用。
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
優點:線程安全,性能高,推薦使用。
缺點:實現稍復雜,使用了 volatile 關鍵字確保變量可見性。
5. 靜態內部類
利用 Java 的類加載機制,線程安全且支持懶加載。
public class Singleton {
private Singleton() {}
// 靜態內部類
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
// 提供全局訪問點
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
優點:線程安全,懶加載,性能高。
缺點:實現稍復雜。
6. 枚舉單例
通過枚舉實現單例模式,是最簡單和推薦的方式之一。
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("單例方法調用");
}
}
優點:天生線程安全,防止反序列化破壞單例,代碼簡單。
缺點:不支持延遲加載(但通常這不是問題)。
測試單例模式
public class SingletonTest {
public static void main(String[] args) {
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1 == singleton2); // true,兩個引用指向同一個實例
}
}
單例模式的優缺點
優點
- 唯一實例:確保系統中只有一個對象,節省資源。
- 全局訪問:提供一個全局訪問點,便于管理。
缺點
- 擴展困難:由于類只能有一個實例,繼承和擴展較難。
- 并發問題:某些實現方式在多線程環境下可能不安全。
使用場景
- 日志記錄器:系統中的日志類只需要一個實例。
- 配置管理:全局配置類,避免重復加載配置。
- 數據庫連接池:確保多個模塊共享同一個連接池。
- 線程池:單例模式可用于管理線程池的全局訪問。
通過以上方式,可以根據需求和場景選擇合適的單例模式實現方式。

浙公網安備 33010602011771號