1. 程式人生 > >java高階設計模式之單例模式

java高階設計模式之單例模式

一、定義

保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。

二、結構和說明

 三、基本實現

四、認識單例模式

   1、單例模式的功能

        單例模式的功能是用來保證這個類的執行期間只會被建立一個類例項,並提供一個全域性唯一訪問這個類例項的訪問點。

    2、單例模式的範圍

       是一個ClassLoader及其子ClassLoader的範圍

    3、單例模式的命名

          一般建議單例模式的方法命名為:getInstance()。

        單例模式的名稱:單例、單件、單體等等,翻譯的不同,都是指的同一個模式。

五、單例模式過程

這裡以懶漢式為例:(懶漢式:執行緒不安全,餓漢式:執行緒安全)

  1. 私有化構造方法、好在內部控制建立例項的數目

        private Singleton(){}

      2、定義一個方法來為客戶端提供類例項。3、這個方法需要定義成類方法,也就是要加static

        public static Singleton getInstance(){

           //6、判斷儲存例項的變數是否有值

                if(instance == null){

                       //6.1、如果沒有,就建立一個類例項,並把值賦值給儲存類例項的變數

                      instance = new Singleton;

                }

              //6.2、返回instance。

          return instance;

          }

4、定義一個變數來儲存建立好的類例項。

5、因為這個變數要在靜態方法中修飾,所以需要加上static修飾

        private Singlenton instance = null;

六、單例模式呼叫時序圖

七、延遲載入思想

什麼是延遲載入呢?

通俗點說,就是一開始不要載入資源或者資料,一直等到馬上就要使用這個資源或者資料了,躲不過去了才載入,所以也稱Lazy Load,不是懶惰,是“延遲載入”,這在實際開發中是一種很常見的思想,儘可能的節約資源。(懶漢式)

八、快取的思想

單例模式的懶漢式實現還體現了快取的思想,快取也是實際開發中非常常見的功能。

簡單講就是,如果某些資源或者資料會被頻繁的使用,可以把這些資料快取到記憶體裡面。每次操作的時候,先到記憶體裡面找,看有沒有這些資料,如果有,那麼就直接使用,如果沒有那麼就獲取它,並設定到快取中,下一次訪問的時候可以直接從記憶體中獲取了。從而節省大量的時間,當然,快取是一種典型的空間換時間的方案。

九、單例模式優缺點

(2)餓漢式是執行緒安全的,因為虛擬機器保證了只會裝載一次。

(3)如何實現懶漢式的執行緒安全呢?載入synchronized即可

(4)雙重檢查加鎖

      所謂雙重檢查加鎖機制,指的是:並不是每次進入getInstance方法都需要同步,而是先不同步,進入方法過後,先檢查例項是否存在,如果不存在才進入下面的同步塊,這是第一重檢查。進入同步塊過後,再次檢查例項是否存在,如果不存在,就在同步的情況下建立一個例項,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步情況下進行判斷所浪費的時間。

      雙重檢查加鎖機制的實現會使用一個關鍵字volatile,它的意思是:被volatile修飾的變數的值,將不會被本地執行緒快取,所有對該變數的讀寫都是直接操作共享記憶體,從而確保多個執行緒能正確的處理該變數。

注意:在Java1.4及以前版本中,很多JVM對於volatile關鍵字的實現有問題,會導致雙重檢查加鎖的失敗,因此本機制只能用在Java5及以上的版本。

十、在java中二種更好的單例實現方式

1、Lazy initialization holder class 模式,這個模式綜合使用了java的類級內部類和多執行緒預設同步鎖的知識,很巧妙的同時實現了延遲載入和執行緒安全。

2、單例和列舉:按照《高效java第二版》中的說法:單元素的列舉型別已經成為實現Singleton的最佳方法。

十一、單例模式的本質:控制例項數目

十二、何時選用單例模式

當需要控制一個類的例項只能有一個,而且客戶只能從一個全域性訪問點訪問它時,可以選用單例模式,這些功能恰好是單例模式要解決的問題。