23種設計模式之——單例模式


什么是單例模式?

保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

什么時候用到它呢?

通常我們可以讓一個全局變量使得一個對象被訪問,但它不能防止你實例化多個對象。

一個最好的方法就是,讓類自身負責保存它的唯一實例。

這個類可以保證沒有其他實例可以被創建,並且它可以提供一個訪問該實例的方法。

單例模式有什么好處呢?

1、單例模式可以保證唯一的實例。

2、單例模式因為Singleton類封裝它的唯一實例,這樣它可以嚴格地控制客戶怎樣訪問它以及何時訪問它。簡單地說就是對唯一實例的受控訪問。

單例模式分為餓漢單例模式和懶漢單例模式。

餓漢單例模式:靜態初始化的方式是在自己被加載時就將自己實例化,所以被形象地稱之為餓漢式單例模式。

懶漢單例模式:要在第一次被引用時,才會將自己實例化,所以就被稱為懶漢式單例模式。

 

懶漢單例模式實現:

Singleton類,定義一個GetInstance操作,允許客戶訪問它的唯一實例。GetInstance是一個靜態方法,主要負責創建自己的唯一實例。

構造方法讓其private,這就堵死了外界利用new創建其實例的可能。

GetInstance()方法是獲得本類實例的唯一全局訪問點。

若實例不存在,則new一個新實例,否則返回已有的實例。

客戶端代碼:

運行結果為:

比較兩次實例化后對象的結果是實例相同。

 

多線程時的單例

在多線程的程序中,多個線程同時,注意是同時訪問Singleton類,調用GetInstance()方法,會有可能造成創建多個實例的。

如何解決呢?

可以給進程一把鎖來處理。synchronized是確保當一個線程位於代碼的臨界區時,另一個線程不進入臨界區。如果其他線程試圖進入鎖定的代碼,則它將一直等待(即被阻止),直到該對象被釋放。

代碼實現:

由於有了synchronized,就保證了多線程環境下的同時訪問也不會造成多個實例的生成。

每次調用GetInstance()都需要synchronized,這種做法會印象性能,所以還需要對該類進行改良。

改良之后的代碼:

先判斷實例是否存在,不存在再加鎖處理。

我們在外面已經判斷能力instance實例是否存在,為什么在synchronized里面還需要在做一次instance實例是否存在的判斷呢?

如果有兩個線程調用GetInstance()方法時,它們將都可以通過第一重instance==null的判斷。

由於synchronized機制,這兩個線程只有一個進入,另一個在排隊等待,必須要其中一個進入並出來后,另一個才能進入。

但是此時如果沒有了第二重instance是否為null的判斷,則第一個線程創建了實例,而第二個線程還是可以繼續再創建新的實例,這樣就沒有達到單例的目的。

 

餓漢單例模式實現:

餓漢單例模式的加載方式是在自己被加載時就將自己實例化了。

喜歡的小伙伴們可以搜索我們個人的微信公眾號“程序員的成長之路”點擊關注或掃描下方二維碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM