04.01 Java開發者:單例模式實現的7種套路,你知道幾個?

Java開發者:單例模式實現的7種套路,你知道幾個?

Java中單例(Singleton)模式是一種廣泛使用的設計模式。為了協調系統整體的行為,一些管理器和控制器常被設計成單例模式。

作用:保證 類在內存中 實例對象的唯一性,節省了系統資源,提高系統性能

一般適用場景

  • 1.避免同個類創建多個實例造成資源的浪費。

  • 2.避免多個實例因多次調用而出現錯誤。

  • 3.一般寫工具類,線程池,緩存,數據庫會用到。

Java開發者:單例模式實現的7種套路,你知道幾個?

基本的實現思路

  • 1.不準在類的外部new對象 —— 構造方法私有化

  • 2.在類的內部中提供創建對象的方法—— 通過new在本類中創建一個實例

  • 3.對外部提供一個獲取該實例的方法 —— 定義公有方法返回創建的實例

餓漢模式與懶漢模式比較

前者在類裝載時就同時實例化,後者只有在第一次被使用時才會實例化。

1. 餓漢模式的優點是沒有線程同步問題,缺點是用不到還會加載,資源浪費。

2. 懶漢模式的優點是實現了懶加載,節省資源,但是需要解決線程安全問題。

Java開發者:單例模式實現的7種套路,你知道幾個?

常見的七種單例模式實現套路

<1>餓漢式,沒有實現懶加載,代碼如下

Java開發者:單例模式實現的7種套路,你知道幾個?

<2>懶漢式

雖然實現了懶加載,線程安全問題還存在,舉例說有兩個線程都剛好執行完條件if(instance == null),然後準備執行instance = new Singleton() 語句,這樣的結果會導致內存中實例化了兩個Singleton對象,為了解決線程不安全問題,可以對getInstance()方法進行加鎖控制。

Java開發者:單例模式實現的7種套路,你知道幾個?

<3>懶漢式加鎖版

為getInstance方法加鎖雖然保證了線程安全,但是每次執行getInstance() 都需要同步,而實例化對象只需要執行一次就夠了,以後獲取時直接return返回就好了,方法同步效率太低,一種改進後的寫法是: synchronized (Singleton.class) { instance = new Singleton(); } 但是,這樣寫依然是線程不安全的,如果你還是想用懶漢式的話,推薦雙重檢查鎖定

(DCL,Double Check Lock)。

Java開發者:單例模式實現的7種套路,你知道幾個?

<4>懶漢式雙重校驗鎖(DCL模式)

在代碼中進行了兩次if檢查,這樣就可以保證線程安全,初始化一次後,後面再次訪問時,if檢查,直接return 實例化對象。volatile關鍵字是在JDK1.5後引入的,volatile關鍵字會屏蔽Java虛擬機所做的一些代碼優化,會導致系統運行效率降低,而更好的寫法是使用靜態內部類來實現單例!

Java開發者:單例模式實現的7種套路,你知道幾個?

<5>靜態內部類實現單例(推薦)

和餓漢式類似,都是通過JVM類加載機制來保證初始化實例的時候只存在一個線程,避免線程安全問題,餓漢式的Singleton類被加載時,就會實例化,而靜態內部類這種,當Singleton類被加載時,不會立即實例化,調用getInstance() 方法才會裝載SingletonHolder類,從而完成Singleton的實例化。

Java開發者:單例模式實現的7種套路,你知道幾個?

<6>枚舉實現單例

INSTANCE即為SingletonEnum類型的引用,得到它就可以調用枚舉中的方法。既避免了線程安全問題,還能防止反序列化重新創建新的對象,但同時也損失了類的一些特性,也沒有延時加載了。

Java開發者:單例模式實現的7種套路,你知道幾個?

<7>容器實現單例

將多種單例類型注入到一個全局的管理類中,在使用時根據key獲取相應實例對象,有些類似工廠模式。可以管理多種類型的單例,在使用時可以通過統一的接口進行獲取,降低了使用成本,也對外部隱藏了具體實現,耦合度得到了降低。

Java開發者:單例模式實現的7種套路,你知道幾個?


分享到:


相關文章: