[讀書筆記] 單例模式的幾種實現方式

來源:互聯網
上載者:User
文章目錄
  • 第一種 (classic)
  • 第二種 (use "synchronize" keyword)
  • 第三種 (eagerly create )
  • 第四種 (雙檢鎖)
  • 第五種(lazy initialization holder class)
  • 第六種(Enum Singleton)

Time:3 hours

    從形式上來看,Singleton Pattern是所有模式中最簡單的一種,但是細究起來並不像想象中那麼簡單。

 

    Singleton的實現有多種方式(見下表及文後所附程式碼範例)。最基本的是第一種實現,這種實現最大的問題就是不支援多線程。《Head First Design Pattern》第五章列舉了三種支援多線程的單例模式實現方式(表中第二、三、四種),這三種實現方式在效能上有所差異。

 

    對於第四種雙檢鎖(DCL)方式,文中特別註明“在Java1.4及更早版本中,許多JVM對volatile關鍵詞的實現,會導致雙重檢查加鎖的實效”;博文[3][4]中對這個問題進行了說明:可能出現instance被賦值,但instance指向的對象尚未初始化完成的情況,此時其他線程若讀取instance,就會有問題。[4]中的原話如下:
    “The problem with DCL is that code of fetching reference to constructed Singleton object does not require synchronization.
Lets say that thread ‘a’ has entered synchronized block, made the instance not null but hasn’t executed the constructor yet. At this stage thread ‘b’ preempts thread ‘a’. Thread ‘b’ checks if the instance is not null, and since its not, it returns reference to a partially constructed Singleton object.”
   從JDK 1.5開始,這個問題已經被解決,DCL方式可正常運行。

 

    《Effective Java》中作者又提及另兩種實現方式:

      第五種 Class holder lazy initialization (見Item 71): 能達到DCL方式一樣的功效,但實現更簡單。Joshua沒有明說,但是從書中他的話來看,對靜態域使用延遲初始化(Singleton模式中正是這種情況),應使用這種方式而不是DCL方式。由於這種方式只適用於靜態域的情況,DCL方式可在執行個體域需要延遲初始化時使用。
      第六種 Enum singleon (見Item 3): Joshua認為雖然這種方式還沒有被廣泛採用,但這是實現Singleton的最佳方法(更簡潔,自動支援序列化機制,絕對防止多次執行個體化)。

   
    在網上尋找”Class holder lazy initialization ”時,發現已經有人總結過Singleton的這些實現方式[4],寫的很清楚(有點小問題:該文介紹DCL方式時,指出了這種方式存在的問題,但未說明JDK1.5開始這個問題已經被解決)。綜合這些資料,列了下面的一覽表:

特徵詞 JDK版本要求 是否Lazy Initialization 是否多安全執行緒 實現難度 說明
第一種 classic   不要求安全執行緒
第二種 use "synchronize" keyword   getInstance()的效能對應用程式不是很關鍵(比如該方法使用不太頻繁)
第三種 eagerly create   建立該執行個體負擔不太繁重;
該執行個體被用到的可能性較大
第四種 雙檢鎖 (double-checked locking) since 1.5 較複雜 getInstance()的效能對應用程式很關鍵;
第五種 Class holder lazy initialization   一般  
第六種 Enum singleton since 1.5 自動支援序列化;不能通過reflection attack來調用私人構造方法

(說明:由於時間關係,博主未對本文的內容進行編程驗證,相關結論根據閱讀的理解整理而來,如有錯誤歡迎指正)

References

[1] Eric Freeman, etc. Head First Design Pattern.
[2] Joshua Bloch. Effective Java. 2nd.
[3] 西坪. Java中的Volatile關鍵字. 2010-12-13. url
[4] InitBinder. Singleton Pattern and Problem With Double Checked Locking. 2008-09-06.  url

 

附各種實現方式的程式碼範例第一種 (classic)

 

第二種 (use "synchronize" keyword)

 

第三種 (eagerly create )

 

第四種 (雙檢鎖)

第五種(lazy initialization holder class)

第六種(Enum Singleton)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.