設計模式之單例模式

1 單例模式的實現場景

創建一個對象需要消耗過多的資源,如要訪問IO和數據庫等資源,爲避免產生多個對象消耗過多資源,需要考慮使用單例模式。

2  實現單例模式的幾個關鍵點

1)構造函數私有化

2)通過一個靜態方法或枚舉返回單例類對象

3)確保單例類的對象有且只有一個,特別是在多線程環境下

4)確保單例類的對象在反序列化時不會重新構建對象

反序列化操作提供了一個很特別的鉤子函數,類中具有一個私有的、被實例化的方法readResolve(),這個方法可以讓開發人員控制對象的反序列化。爲防止這種情況,需加入如下方法:

private Object readResolve() throws ObjectStreamException

{

return sInstance;

}

也就是在readResolve()方法中將sInstance對象返回,而不是默認的重新生成一個新的對象。

3  單例模式實現的幾種方式

懶漢式和DCL方式不建議使用,這裏都不做介紹。

3.1  餓漢式

public class Singleton

{

private static Singleton instance = new Singleton();

private Singleton()

{

}

public static Singleton getInstance()

{

return instance;

}

}

優點:簡單。

缺點:第一次加載Singleton類時instance就被實例化,不管是否被使用,不是按需進行實例化。

3.2  靜態內部類單例模式

public class Singleton

{

private Singleton()

{

}

public static Singleton getInstance()

{

return SingletonHolder.sInstance;

}

private static class SingletonHolder

{

private static final Singleton sInstance = new Singleton();

}

}

這是推薦使用的單例模式實現方式。

3.3  枚舉單例

public enum SingletonEnum

{

INSTANCE;

public void doSomething()

{

........

}

}

只用SingletonEnum.INSTANCE即可獲得所需實例,默認枚舉實例的創建是線程安全的,並且在任何情況下它都是一個單例。不像以上方式,在反序列化時可以通過鉤子函數readResolve()去創建新的實例。枚舉不存在這個問題,反序列化也不會生成新的實例。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章