Java設計模式之Singleton——四種不同的單例模式(Singleton)
單例模式(Singleton [?sglt?n])
如果要保證系統裡最多隻能存在一個例項時,我們就需要單例模式。例如快取池、資料庫連線池等。
例項一:最簡單的單例模式
因為JVM在載入類時,對於static屬性的初始化只能由一個執行緒執行且僅執行一次,並且return操作是原子性的,所以,該方式是執行緒安全的。
例項二:延遲建立的單例模式(出於效能等方面的考慮)
延遲建立:在呼叫方法的時候建立例項,而不是在類載入的時候建立,這樣可以提高效能。 雖然延遲建立的方式可以提高效能,但是,它不是執行緒安全的。因為可能存在多個執行緒同時訪問程式碼塊:
這樣就會建立多個DelayBuildSingleton例項。為了解決這個問題,
例項三:Double-Check Locking
不瞭解volatile以及synchronized相關知識的,推薦先閱讀《Thining in Java》併發章節。 volatile關鍵字保證了instance的可視性,synchronized程式碼塊保證了例項化操作的原子性。他們一起協作,使得該方法是執行緒安全的。(關於volatile關鍵字,推薦一篇詳解部落格:http://www.importnew.com/18126.html) 該方式同時保證了執行緒安全和延遲建立。還有一種方式同樣可以達到此目的:
例項四:使用靜態私有內部類
只有在第一次呼叫getInstance()方法時,JVM才會載入LazyHolder類,並初始化靜態變數instance,這實現了延遲載入。同例項1一樣,該方式是執行緒安全的。
上面介紹了四種單例模式的實現方式。具體使用時,我們應該根據具體上下文環境來選擇。比如,在多執行緒環境下,應該選用執行緒安全的方式,如例項一、三、四。當效能需要優化時,則考慮例項二、例項四。通常情況下,例項四是推薦的方式,因為它同時滿足了效能和執行緒安全,同時代碼也並不複雜。