這不是討論Singleton是好還是壞。這是關於創建單身人士。我理解辛格爾頓的方式是,它是一個在任何時候都應該存在多於一個對象的類。這就是說,如果幾個類同時實例化一個單例,那麼它們將共享該單例的單個實例。
單身人員的問題在於,一旦創建它,它將在應用程序的持續時間內存在。使用我的方法,您可以創建並隨時收集單身垃圾,如果它不再被使用。那麼我需要一個枚舉(Singleton!)來創建所有其他的Singleton。我認爲我的方法是反射和序列化安全,但我不確定線程是否有問題。
我的方法來創建單情況如下:這是創建Singleton線程安全的方法嗎?
首先任何類,它想成爲單身必須擴展以下類
public abstract class Singleton {
public Singleton(SingletonFactory.SingletonParam singletonParam) {
if (singletonParam == null) {
throw new NullPointerException("singletonParam cannot be null)");
}
}
// For singleton to release resources.
public abstract void destroy(SingletonFactory.SingletonParam singletonParam);
}
SingletonParam將是不能有一個抽象類,內部類對象,它是一個多態意義上的SingletonParam,在其容器類的外部實例化。
這不是要讓子類在運行時擴展Singleton類。它是由具有靜態實例的單例類組成的。我的方法不需要單例類的任何靜態實例。
容器是下面的類
注:讀斯蒂芬C中的答案後,我作出改變,以初始化從構造函數中的HashMap和我不明白爲什麼它不是線程安全的。
public enum SingletonFactory {
INSTANCE;
enum SingletonList {
A,
B,
......
}
private final HashMap<String, SingletonInfo> mfSingletonInfoHashMap = new HashMap<>();
// Added after @Stephen C answer
SingletonFactory() {
mfSingletonInfoHasmap.put(A, final new SingletonInfo());
// put all the members of the SingletonList here.
At this time the Singleton member of the SingletonInfo is null.
It will be instantiated when a class call getSingleton
}
private class SingletonInfo {
final Set callingObjects = new HashSet();
Singleton singleton;
}
public Object getSingleton(SingletonList inList, Object object) {
final SingletonInfo singletonInfo = mfSingletonInfoHashMap.get(inList);
synchronized (singletonInfo) {
if (singletonInfo.callingObjects.add(object)) {
if (singletonInfo.singleton == null) {
singletonInfo.singleton = createSingleton(singletonClassName);
}
} else {
throw new RuntimeException("getSingleton(" + singletonClassName + ") has already been called and not released");
}
return singletonInfo.singleton;
}
public void releaseSingleton(SingletonList inList, Object object) {
SingletonInfo singletonInfo = mfSingletonInfoHashMap.get(inList);
synchronized (singletonInfo) {
singletonInfo.callingObjects.remove(object);
if (singletonInfo.callingObjects.isEmpty()) {
singletonInfo.singleton.destroy(new SingletonParam() {
});
singletonInfo.singleton = null;
}
}
}
private Singleton createSingleton(SingletonList inList) {
switch(inList) {
case SingletonA:
return new SingletonA(new SingletonParam() {});
......
}
}
public abstract class SingletonParam {
private SingletonParam() {
}
}
}
遠高於並不完全正確,因爲你必須擴展包含在SingletonInfo的CallingObjects落實參考平等和默認實現不等於HashSet的。
由於一個子類的實例無法通過調用SingletonFactory.INSTANCE.getSingleton(you_singleton_class_name, this)
你爲什麼不使用'WeakReference'? – shmosel
WeakReference是什麼? –
給你想要成爲垃圾收集者的單身人士。 – shmosel