singleton 类_在Java中对Singleton类进行双重检查锁定
singleton 類
Singleton類在Java開發(fā)人員中非常常見,但是它給初級開發(fā)人員帶來了許多挑戰(zhàn)。 他們面臨的主要挑戰(zhàn)之一是如何使Singleton保持為Singleton? 也就是說,無論出于何種原因,如何防止單個實(shí)例的多個實(shí)例。 對Singleton進(jìn)行雙重檢查鎖定是一種確保在應(yīng)用程序生命周期中僅創(chuàng)建Singleton類的一個實(shí)例的方法。 顧名思義,在兩次檢查鎖定中,代碼對一次Singleton類的現(xiàn)有實(shí)例進(jìn)行兩次檢查(不進(jìn)行雙重鎖定),以確保不會創(chuàng)建一個以上的singleton實(shí)例。 順便說一句,它在Java修復(fù)JDK 1.5中的內(nèi)存模型問題之前就被破壞了。 在本文中,我們將看到如何為Java中的Singleton的雙重檢查鎖定編寫代碼 ,為什么在Java 5之前雙重檢查鎖定被破壞以及如何解決。 順便說一句,從訪談的角度來看,這也很重要,我聽說有人要求對金融和服務(wù)業(yè)的公司進(jìn)行手工雙重檢查Singleton鎖定的代碼,并相信我很棘手,直到您清楚地了解了什么你在做。 您還可以查看我的Singleton設(shè)計模式問題的完整列表,以進(jìn)行良好的準(zhǔn)備。
Singleton類破壞其合同的一種常見情況是多線程。 如果您要求初學(xué)者為Singleton設(shè)計模式編寫代碼,那么他很有可能會提出以下內(nèi)容:
private static Singleton _instance;public static Singleton getInstance() {if (_instance == null) {_instance = new Singleton();}return _instance; }并且當(dāng)您指出這段代碼將由多個線程并行調(diào)用時,將創(chuàng)建Singleton類的多個實(shí)例時,他可能會使整個getInstance()方法同步化 ,如第二個代碼示例getInstanceTS()方法所示。 盡管它是線程安全的,并且可以解決多個實(shí)例的問題,但效率不是很高。 每次調(diào)用此方法時,都需要承擔(dān)同步的費(fèi)用,而創(chuàng)建Singleton實(shí)例時,僅在第一類上才需要同步。 這將使我們進(jìn)入雙重檢查的鎖定模式 ,即只有關(guān)鍵的代碼段被鎖定。 程序員稱其為“雙重檢查鎖定”,因?yàn)閷instance == null進(jìn)行了兩次檢查,一次沒有鎖定,而另一次則帶有鎖定(內(nèi)部同步)塊。 這是Java中經(jīng)過雙重檢查的鎖定的樣子:
public static Singleton getInstanceDC() {if (_instance == null) { // Single Checkedsynchronized (Singleton.class) {if (_instance == null) { // Double checked_instance = new Singleton();}}}return _instance; }
從表面上看,這種方法看起來很完美,因?yàn)槟恍枰獮橥綁K支付一次費(fèi)用,但是直到使_instance變量為volatile時,它還是壞了。 如果沒有volatile修飾符,則Java中的另一個線程可能會看到_instance變量的一半初始化狀態(tài),但是由于volatile變量保證了before-before關(guān)系的發(fā)生,所有寫操作都會在_instance變量的任何讀取之前發(fā)生在volatile _instance上。 在Java 5之前不是這種情況,這就是為什么以前雙重檢查鎖定已被破壞的原因。 現(xiàn)在,有了事前保證 ,您可以放心地認(rèn)為這將起作用。 順便說一下,這不是創(chuàng)建線程安全的Singleton的最佳方法,可以將Enum用作Singleton ,它在實(shí)例創(chuàng)建過程中提供內(nèi)置的線程安全性。 另一種方法是使用靜態(tài)持有人模式。
這就是有關(guān)Java中Singleton類的雙重檢查鎖定的全部內(nèi)容。 這是在Java中創(chuàng)建線程安全的Singleton的有爭議的方法之一,就將Enum用作Singleton類而言,還有其他更簡單的選擇。 我不建議您像這樣實(shí)現(xiàn)Singleton,因?yàn)橛性S多更好的方法可以在Java中實(shí)現(xiàn)Singleton模式。 雖然,這個問題具有歷史意義,并且還教導(dǎo)了并發(fā)如何引入細(xì)微的錯誤。 正如我之前所說,從訪談的角度來看,這非常重要。 在進(jìn)行任何Java面試之前,練習(xí)手工編寫Singleton類的雙重檢查鎖定。 這將使您深入了解Java程序員的編碼錯誤。 與此相關(guān)的是,在現(xiàn)代的測試驅(qū)動開發(fā)中,由于Singleton難以模擬其行為,因此Singleton被視為反模式,因此,如果您是TDD實(shí)踐者,最好避免使用Singleton模式。
翻譯自: https://www.javacodegeeks.com/2014/05/double-checked-locking-on-singleton-class-in-java.html
singleton 類
總結(jié)
以上是生活随笔為你收集整理的singleton 类_在Java中对Singleton类进行双重检查锁定的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 口罩备案号(囗罩备案)
- 下一篇: java美元兑换,(Java实现) 美元