Design Pattern-Singleton Pattern單例模式

There are many objects we only need one of: thread pools, caches, dialog boxes, objects that handle preferences and registry settings, objects used for logging, and objects that act as device drivers to devices like printers and graphics cards. In fact, for many of these types of objects, if we were to instantiate more than one we'd run into all sorts of problems like incorrect program behavior, overuse of resources, or inconsistent results.

有一些對象我們只需要一個:線程池、緩存、對話框、偏好處理和註冊表設置對象、日誌對象、充當打印機、顯卡等設備的驅動程序的對象。事實上,很多這類型的對象,如果我們實例化多個會導致各種問題,比如:程序的異常行爲、資源的過量使用、或者不一致的結果。

(來源於《Head First Design Pattern》 P170)

Definition: The Singleton Pattern ensures a class has only one instance, and provides a global point of access to it.

(來源於《Head First Design Pattern 》P177)

如何創建單例模式懶漢式餓漢式

1) 構造方法私有化

2)在類的內部創建對象

3)創建一個靜態的公有的方法,返回實例化了的單例。

 

懶漢式

用同步去處理多線程,防止創建兩個對象,但同步會降低性能,同步一個方法會使性能下降100倍

範例:(感覺自己的程序很好喫)

餓漢式 :Move to an eagerly created instance rather than a lazily created one 急切創建實例,而非延遲創建

範例:(靈感來自於每天上課餓了)

擴展:Use "double-checked looking" to reduce the use of synchronization in getInstance()

           使用“雙重檢查加鎖”去減少在getInstance()中使用同步

         We first check to see if an instance is created, and if not, then we synchronize. This way, we only synchronize the first time through.

         首先檢查實例是否已經創建,如果沒有創建,才使用同步。這樣,我們只有在第一次纔會使用到同步。

public class Singleton(){

                privatevolatile static Singleton uniqueInstance;

                private Singleto(){}

                public static Singleton getInstance(){

                      //檢查實例,如果不存在,就進入同步區

                      if(uniqueInstance == null){

                      //只有第一次才徹底執行這裏的代碼

                                 synchronized (Singleton.class){

                                         //進入同步區後再檢查一次,若仍爲null,才創建實例

                                         if(uniqueInstance == null)

                                                 uniqueInstance = new Singleton();

                                  }

                          }

                     return uniqueInstance;

               }

}

The volatile keyword ensure that multiple threads handle the uniqueInstance variable correctly when it is being initialized to the Singleton instance.

volatile關鍵字確保,當uniqueInstance變量實例化單例時,多個線程能正確地處理uniqueInstance變量。

(來源於《Head First Design Pattern 》P182)

擴展volatile關鍵字

 

Java 語言包含兩種內在的同步機制:同步塊(或方法)和 volatile 變量。這兩種機制的提出都是爲了實現代碼線程的安全性。其中 volatile變量的同步性較差(但有時它更簡單並且開銷更低),而且其使用也更容易出錯。

Java 語言中的 volatile變量可以被看作是一種 “程度較輕的 synchronized”;與 synchronized 塊相比,volatile 變量運行時開銷較少,但是它所能實現的功能也僅是 synchronized 的一部分。

鎖提供了兩種主要特性:互斥(mutual exclusion) 和可見性(visibility)

1)互斥:一次只允許一個線程持有某個特定的鎖,即一次只有一個線程能夠使用共享數據。

2)可見性:它必須確保釋放鎖之前對共享數據做出的更改對於隨後獲得該鎖的另一個線程是可見的  若沒有同步機制提供可見性保證,線程看到的共享變量可能是修改前的值或不一致的值,這將引發許多嚴重問題。

 

擴展三:框架中的單例模式

1.Struts2中的Action是多例的而非單例,一個Session產生一個Action,每一次請求產生一個Action。

   原因:因爲Struts2中的Action存放着數據,好比在頁面填寫表單數據時,數據可以以Action屬性傳輸的方式傳送到後臺。若Action爲單例,在多線程的情況下會造成數據的傳輸錯誤或泄露。但有的Action規定只能由Admin使用,這時就可以將Action設爲單例。

2.Spring的IOC容器管理的bean默認是單例的,但在配置Action bean時,可以通過配置scope來設定是單例或是多例。

 

 

 

 

 

 

 

 

 

 

 

 

 

         

 

 

 

 

 

 

 

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