單例模式確保一個類只有一個實例,並提供一個全域訪問點。
在 Java 中,實現單例模式有以下幾種常見的方法。
餓漢式#
餓漢式在類加載時就創建實例,線程安全但可能會浪費內存。
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
// 私有化構造函數,防止外部實例化
private Singleton() {}
// 提供全域訪問點
public static Singleton getInstance() {
return INSTANCE;
}
}
線程不安全的懶漢式#
懶漢式在第一次調用getInstance()
時創建實例,線程不安全。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
線程安全的懶漢式#
通過同步方法,確保多線程環境下也只有一個實例。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
雙重鎖定檢查#
在同步塊內外都檢查實例是否已創建,減少了同步開銷。
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;
}
}
靜態內部類#
使用靜態內部類,線程安全且延遲加載。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
枚舉#
最簡單的一種實現方式,推薦使用。線程安全,支持序列化並且能夠防止反射攻擊。
public enum Singleton {
INSTANCE;
public void someMethod() {
// 實例方法
}
}