設計模式-單例模式

設計模式-單例模式

定義

單例模式(singleton pattern)是確保一個類在任何情況下都絕對只有一個實例,并提供一個全局訪問點。

單例模式是創(chuàng)建型模式。

分類

1、餓漢式(餓漢和靜態(tài)餓漢)

2、懶漢式(線程安全要加鎖)

3、枚舉式(注冊)初始化即生成,餓漢式,可以保證不被反射機制和反序列化破壞,是借助JDK的特性,所以最官方、最權威、最穩(wěn)定

4、序列化單例模式(可以解決反序列化問題,但是內存開銷依然很大)

5、容器式單例模式(容器式單例模式適用于需要大量創(chuàng)建單例對象的場景,便于管理。但它是非線程安全的)

6、threadLocal單例模式(不能保證其創(chuàng)建的對象是全局唯一的,但是能保證在單個線程中是唯一的,天生是線程安全的)

總結

????單例模式可以保證內存中只有一個實例,減少了內存開銷,還可以避免對資源的多重占用。

單例模式的常見應?場景

單例模式(Singleton)也叫單態(tài)模式,是設計模式中最為簡單的?種模式,甚?有些模式?師都不稱其為模式,稱其為?種實現(xiàn)技巧,因為設計模式講究對象之間的關系的抽象,?單例模式只有???個對象,也因此有些設計?師并把把其稱為設計模式之?。

好多沒怎么使?過的?可能會想,單例模式感覺不怎么?到,實際的應?場景有哪些呢?以下,我將列出?些就在咱們周邊和很有意義的單例應?場景。

1. Windows的Task Manager(任務管理器)就是很典型的單例模式(這個很熟悉吧),想想看,是不是呢,你能打開兩個windows task manager嗎? 不信你??試試看哦~

2. windows的Recycle Bin(回收站)也是典型的單例應?。在整個系統(tǒng)運?過程中,回收站?直維護著僅有的?個實例。

3. ?站的計數(shù)器,?般也是采?單例模式實現(xiàn),否則難以同步。

4. 應?程序的?志應?,?般都何?單例模式實現(xiàn),這?般是由于共享的?志?件?直處于打開狀態(tài),因為只能有?個實例去操作,否則內容不好追加。

5. Web應?的配置對象的讀取,?般也應?單例模式,這個是由于配置?件是共享的資源。

6. 數(shù)據(jù)庫連接池的設計?般也是采?單例模式,因為數(shù)據(jù)庫連接是?種數(shù)據(jù)庫資源。數(shù)據(jù)庫軟件系統(tǒng)中使?數(shù)據(jù)庫連接池,主要是節(jié)省打開或者關閉數(shù)據(jù)庫連接所引起的效率損耗,這種效率上的損耗還是?常昂貴的,因為何?單例模式來維護,就可以??降低這種損耗。

7. 多線程的線程池的設計?般也是采?單例模式,這是由于線程池要?便對池中的線程進?控制。

8. 操作系統(tǒng)的?件系統(tǒng),也是?的單例模式實現(xiàn)的具體例?,?個操作系統(tǒng)只能有?個?件系統(tǒng)。

9. HttpApplication 也是單位例的典型應?。熟悉ASP.Net(IIS)的整個請求?命周期的?應該知道HttpApplication也是單例模式,所有的HttpModule都共享?個HttpApplication實例.

? 總結以上,不難看出:

單例模式應?的場景?般發(fā)現(xiàn)在以下條件下:

(1)資源共享的情況下,避免由于資源操作時導致的性能或損耗等。如上述中的?志?件,應?配置。

(2)控制資源的情況下,?便資源之間的互相通信。如線程池等。

單例模式優(yōu)點:

1、在內存中只有一個實例,減少了內存開銷。

2、可以避免資源的多重占用。

3、設置全局訪問點,嚴格控制訪問。

單例模式的缺點:

1、沒有接口,擴展困難。

2、如果要擴展單例對象,只有修改代碼,沒有其他途徑。

代碼實例

1.1、餓漢式單例模式:類加載時立即初始化,并且創(chuàng)建單例對象。它絕對線程安全,在線程還沒出現(xiàn)就實例化了,不存在訪問安全問題。但是會導致內存浪費.
1.2、餓漢式單例模式(靜態(tài)代碼塊):同第一種,唯一不同就是多點逼格O .O
2.1懶漢式單例模式,添加synchronized關鍵字后,解決了傳統(tǒng)懶漢模式的線程安全問題,但是每次都要獲取鎖,性能較低.
2.2懶漢式單例模式改進(雙重檢查鎖):可以有效的提高運行效率,那么我們可不可以不使用鎖?
2.3懶漢式單例模式改進(靜態(tài)內部類):這種形式來兼顧餓漢式單例模式的內存浪費問題和 synchronized 的性能問題(完美的屏蔽了這兩個缺點) ,它還可以防止被反射破壞單例機制.到目前為止,這種寫法基本上已經(jīng)是最牛的啦,,但是依然可以被反序列化破壞(逐漸開始杠精起來...)
3.1、枚舉類單例模式(屬于注冊式單例模式的一種):初始化即生成,餓漢式,可以保證不被反射機制和反序列化破壞,是借助JDK的特性,所以最官方、最權威、最穩(wěn)定,因此枚舉式單例模式是《Effective java》書中推薦的一種單例模式實現(xiàn)方法。
3.2、容器式單例模式(屬于注冊式單例模式的第2種):適用于需要大量創(chuàng)建單例對象的場景,便于管理。但它是非線程安全的。
4、序列化單例模式:反序列化導致單例模式被破壞,加上readResolve方法,可以解決反序列化問題,但是內存開銷依然很大.
5、線程單例實現(xiàn)ThreadLocal:不能保證其創(chuàng)建的對象是全局唯一的,但是能保證在單個線程中是唯一的,天生是線程安全的。這個方式適合一些特定場景.

學習單例模式的知識重點總結

1、私有化構造器

2、保證線程安全

單例模式可以保證內存里只有一個實例,減少了內存的開銷,還可以避免對資源的多重占用。單例模式看起來非常簡單,實現(xiàn)起來其實也非常簡單,但是在面試中卻是一個高頻面試點。希望“小伙伴們”通過本章的學習,對單例模式有了非常深刻的認識,在面試中彰顯技術深度,提升核心競爭力,給面試加分,順利拿到錄取通知(Offer)。

擴展

1、解決容器式單例的線程安全問題。

兩種方法:雙重檢查鎖,利用ConcurrentHashMap#putIfAbsent()方法的原子性。

public class ContainerSingleton {

????private static Map ioc = new ConcurrentHashMap();

????private ContainerSingleton() {

? ? ? ? ????throw new RuntimeException("不可被實例化!");

????}

? ? // 方法一:雙重檢查鎖

????public static Object getInstance(String className) {

????????Object instance = null;

????????if (!ioc.containsKey(className)) {

????????????synchronized (ContainerSingleton.class) {

????????????????if (!ioc.containsKey(className)) {

????????????????????try {

????????????????????????instance = Class.forName(className).newInstance();

????????????????????????ioc.put(className, instance);

? ? ? ? ? ? ? ? ? ? } catch (Exception e) {

????????????????????????e.printStackTrace();

????????????????????}

????????????????return instance;

????????????????} else {

????????????????????return ioc.get(className);

????????????????}

????????????}

????????}

????????return ioc.get(className);

????}

? ? // 方法二:利用ConcurrentHashMap#putIfAbsent()方法的原子性

public static Object getInstance1(String className){

????Object instance = null;

????try {

????????ioc.putIfAbsent(className, Class.forName(className).newInstance());

????}catch (Exception e){

????????e.printStackTrace();

????}

????return ioc.get(className);

????}

}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容