單例(Java)
Java 中的單例與 C#非常相似,因為兩種語言都是物件導向的。下面是一個單例類的示例,其中只有一個版本的物件可以在程式的生命週期記憶體活(假設程式在一個執行緒上工作)
public class SingletonExample {
private SingletonExample() { }
private static SingletonExample _instance;
public static SingletonExample getInstance() {
if (_instance == null) {
_instance = new SingletonExample();
}
return _instance;
}
}
這是該程式的執行緒安全版本:
public class SingletonThreadSafeExample {
private SingletonThreadSafeExample () { }
private static volatile SingletonThreadSafeExample _instance;
public static SingletonThreadSafeExample getInstance() {
if (_instance == null) {
createInstance();
}
return _instance;
}
private static void createInstance() {
synchronized(SingletonThreadSafeExample.class) {
if (_instance == null) {
_instance = new SingletonThreadSafeExample();
}
}
}
}
Java 還有一個名為 ThreadLocal
的物件,它以執行緒為基礎線上程上建立物件的單個例項。這在每個執行緒都需要自己的物件版本的應用程式中非常有用
public class SingletonThreadLocalExample {
private SingletonThreadLocalExample () { }
private static ThreadLocal<SingletonThreadLocalExample> _instance = new ThreadLocal<SingletonThreadLocalExample>();
public static SingletonThreadLocalExample getInstance() {
if (_instance.get() == null) {
_instance.set(new SingletonThreadLocalExample());
}
return _instance.get();
}
}
這裡也是一個使用 enum
的 Singleton 實現(只包含一個元素):
public enum SingletonEnum {
INSTANCE;
// fields, methods
}
任何 Enum 類實現都確保每個元素只存在一個例項。
Bill Pugh Singleton 模式
Bill Pugh Singleton Pattern 是 Singleton 類使用最廣泛的方法,因為它不需要同步
public class SingletonExample {
private SingletonExample(){}
private static class SingletonHolder{
private static final SingletonExample INSTANCE = new SingletonExample();
}
public static SingletonExample getInstance(){
return SingletonHolder.INSTANCE;
}
}
使用私有內部靜態類,持有者不會載入到記憶體,直到有人呼叫 getInstance 方法。Bill Pugh 解決方案是執行緒安全的,不需要同步。
Java 文件標記下的 Singletons 主題中有更多 Java 單例示例。