天天看點

單例模式

單例對象(singleton)是一種常用的設計模式。在java應用中,單例對象能保證在一個jvm中,該對象隻有一個執行個體存在。

這樣的模式有幾個好處:

1、某些類建立比較頻繁,對于一些大型的對象,這是一筆很大的系統開銷。

2、省去了new操作符,降低了系統記憶體的使用頻率,減輕gc壓力。

3、有些類如交易所的核心交易引擎,控制着交易流程,如果該類可以建立多個的話,系統完全亂了。(比如一個軍隊出現了多個司令員同時指揮,肯定會亂成一團),是以隻有使用單例模式,才能保證核心交易伺服器獨立控制整個流程。

uml圖:

首先我們寫一個簡單的單例類:

主要的幾種實作方式:

如果考慮多線程,那麼getinstance()方法要加同步synchronized,這時餓漢式比懶漢式要好,盡管資源使用率要差,但是不用同步。

通過單例模式的學習告訴我們:

1、單例模式了解起來簡單,但是具體實作起來還是有一定的難度。

2、synchronized關鍵字鎖定的是對象,在用的時候,一定要在恰當的地方使用(注意需要使用鎖的對象和過程,可能有的時候并不是整個對象及整個過程都需要鎖)。

到這兒,單例模式基本已經講完了,結尾處,筆者突然想到另一個問題,就是采用類的靜态方法,實作單例模式的效果,也是可行的,此處二者有什麼不同?

首先,靜态類不能實作接口。(從類的角度說是可以的,但是那樣就破壞了靜态了。因為接口中不允許有static修飾的方法,是以即使實作了也是非靜态的)

其次,單例可以被延遲初始化,靜态類一般在第一次加載是初始化。之是以延遲加載,是因為有些類比較龐大,是以延遲加載有助于提升性能。

再次,單例類可以被繼承,他的方法可以被覆寫。但是靜态類内部方法都是static,無法被覆寫。

最後一點,單例類比較靈活,畢竟從實作上隻是一個普通的java類,隻要滿足單例的基本需求,你可以在裡面随心所欲的實作一些其它功能,但是靜态類不行。從上面這些概括中,基本可以看出二者的差別,但是,從另一方面講,我們上面最後實作的那個單例模式,内部就是用一個靜态類來實作的,是以,二者有很大的關聯,隻是我們考慮問題的層面不同罷了。兩種思想的結合,才能造就出完美的解決方案,就像hashmap采用數組+連結清單來實作一樣,其實生活中很多事情都是這樣,單用不同的方法來處理問題,總是有優點也有缺點,最完美的方法是,結合各個方法的優點,才能最好的解決問題!