Singleton
使用時機使用時機
在設計階段你知道所要產生物件的具體類別。
- 你所要產生的物件,代表某種單一(而且通常是共享)的資源,例如檔案系統、I/O Port。
- 這種單一資源物件,本身會紀錄某些狀態,
- 針對這種單一資源,只需要產生一個物件來代表就可以了。如果產生多份物件但卻代表相同的資源,不只浪費記憶體,還要確保這多份物件狀態必須一致,會增加程式的複雜度。
from: Creational Patterns要解決什麼問題(中)?
實作方法
方法1: lazy Initialization
not thread-safe
public class Singleton {
private static Singleton instance;
private Singleton (){};
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
方法2: lazy Initialization + synchronized
thread-safe,但效能不好
public class Singleton {
private static Singleton instance;
private Singleton (){};
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
方法3: double-checked locking
第一次建立實例才會做同步
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){};
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
方法4:
class 加載時就初始化,浪費記憶體
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){};
public static Singleton getInstance() {
return instance;
}
}
方法5: initialization demand holder
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){};
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
方法6: 使用 enum
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
from: 設計模式乾貨系列:(四)單例模式