在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;
}
}
這種方法是線程安全的,通過雙重檢查鎖定(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;
}
}
枚舉是實現單例模式的一種簡潔且線程安全的方式。
public enum Singleton {
INSTANCE;
public void doSomething() {
// 業務邏輯
}
}
這種方法是線程安全的,并且實現了延遲加載。
public class Singleton {
private Singleton() {
// 私有構造函數防止外部實例化
}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
雖然不推薦,但可以通過反射和序列化來破壞單例模式。為了防止這種情況,可以在單例類中添加相應的檢查和處理邏輯。
import java.io.Serializable;
public class Singleton implements Serializable {
private static final long serialVersionUID = 1L;
private static final Singleton INSTANCE = new Singleton();
private Singleton() {
// 私有構造函數防止外部實例化
}
public static Singleton getInstance() {
return INSTANCE;
}
protected Object readResolve() {
return getInstance();
}
}
選擇哪種實現方式取決于具體的需求和場景。如果需要線程安全且延遲加載,可以使用靜態內部類或枚舉;如果對性能有較高要求,可以使用餓漢式或雙重檢查鎖定。