亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java怎么實現雙重校驗鎖單例

發布時間:2022-01-21 17:09:26 來源:億速云 閱讀:167 作者:iii 欄目:開發技術

這篇文章主要介紹了Java怎么實現雙重校驗鎖單例的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Java怎么實現雙重校驗鎖單例文章都會有所收獲,下面我們一起來看看吧。

    代碼實現

    Java代碼實現如下:

    //雙重校驗鎖單例
    public class SingleInstance {
        //必須volatile修飾 見分析1
        private volatile static SingleInstance instance;
        //私有化構造函數
        private SingleInstance() {
        }
     
        public static SingleInstance getInstance() {
            //第一個判空 見分析2
            if (instance == null) {
                synchronized (SingleInstance.class) {
                    //第二個判空 見分析3
                    if (instance == null) {
                        //新建實例
                        instance = new SingleInstance();
                    }
                }
            }
            return instance;
        }
    }

    首先這里synchronized關鍵字沒有修飾整個getInstance函數,因為這個函數可能使用地方很多,這樣就會造成其他線程阻塞,不太好,所以這里只同步了一段代碼。

    分析2:為什么在進入同步代碼塊時需要進行進行判空,假如有線程A和線程B,這時線程A先判斷instance為null,所以它進入了同步代碼塊,創建了對象,然后線程B再進來時,它就不必再進入同步代碼快了,可以直接返回,也其實也就是懶加載,可以加快執行速度。

    分析3:為什么在同步代碼塊中還要再進行一次判斷呢,假如有線程A和線程B,它倆A先調用方法,B緊接著調用,這時A、B在分析2出的判空都是空,所以A進入同步代碼塊,B進行等待,當A進入同步代碼塊中創建了對象后,A線程釋放了鎖,這時B再進入,如果這時不加分析3的判空,B又會創建一個實例,這明顯不符合規矩。

    分析1:那既然加了2層判斷,那為什么還要加個volatile關鍵字呢,這里知識點就有點多了。

    因為新建實例的代碼:

    instance = new SingleInstance();

    它不是一個原子操作,這個簡單的賦值可以分為3步:

    1、給SingleInstance分配內存

    2、調用SingleInstance的構造方法

    3、把instance指向分配的內存空間

    這是正常邏輯的3個步驟,也只有按1 2 3執行后,這個instance才不是null。

    但是Java內存模型允許這個進行指令重排序,也就是這3步可能是123也可能是132,所以這里就有問題了。

    假如線程A和線程B,線程A已經跑到分析3處的代碼,這時這條指令執行是132,剛把步驟3執行完,這時線程B跑到了分析1處的代碼,會發現instance不為null了,這時線程B就直接返回了,從而導致錯誤。

    既然知道了原因,那volatile關鍵字就是解決這個的,它可以禁止指令重新排序,而且保證所有線程看到這個變量是一致的,也就是不會從緩存中讀取(這個特性后面有機會再說),所以在創建instance實例時,它的步驟都是123,就不會出錯了。

    關于“Java怎么實現雙重校驗鎖單例”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Java怎么實現雙重校驗鎖單例”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    荣昌县| 乌拉特中旗| 富阳市| 遂宁市| 浑源县| 青浦区| 凌源市| 澜沧| 平果县| 武义县| 房山区| 德钦县| 来凤县| 塔城市| 光山县| 阿瓦提县| 荣成市| 南郑县| 沙雅县| 宁夏| 太和县| 共和县| 额尔古纳市| 普宁市| 察隅县| 永德县| 阿图什市| 恩平市| 弥勒县| 陆川县| 余干县| 木兰县| 西峡县| 黄冈市| 张家川| 五莲县| 乌什县| 闽侯县| 芒康县| 南川市| 洪江市|