單例模式雙檢驗鎖中的volatile理解

2021-10-22 23:29:45 字數 759 閱讀 8905

public

class

singleton

public

static singleton getuniqueinstance()

}}return uniqueinstance;

}}

我們都知道在synchronized可以保證變數的可見性和操作的原子性,此處volatile為什麼是必要的的呢?

物件的建立可以粗略分為三步

1、分配記憶體

2、初始化uniqueinstance

3、uniqueinstance指向分配的記憶體空間

建立物件可能出現指令重排的現象,例如1>>>3>>>2,單執行緒情況沒有什麼問題,但是如果執行緒1先執行了1和3,物件還未初始化完全,執行緒2進入if語句,發現其不為null,直接返回了沒有初始化的物件,發生錯誤,因此我們必須保證步驟3,即uniqueinstance在最後一步才執行,使用volatile在此處的目的不是保障變數可見性,而是防止指令重排;

同時,在懶漢執行緒安全模式中,我發現其與猶豫模式balking有異曲同工之妙,同樣保證了一段臨界區**只會被執行一次。

它和synchronized這種要注意區分,什麼時候用balking什麼時候用synchronized呢?

synchronized保證的是原子性,是防止同時執行的概念,但是多個執行緒仍然可以交替或者順序執行**塊內容多次,而使用猶豫模式可以保證即使有多個執行緒,這個**塊也只執行一次。例如此處uniqueinstance=new singleton();

單例模式 雙層檢驗鎖

單例模式 雙重校驗鎖 懶漢模式 public class singleton 私有化構造方法 private static volatile singleton singleton null public static singleton getinstance return singleton p...

java單例模式中的雙重檢驗鎖

public class doublecheck public static doublecheck getsingleton return instance 首先判斷instance是否為null,如果確實為null,則進入乙個synchronize包圍的 塊,相當於上了鎖,進入了臨界區,為了防止...

單例模式 雙層檢驗鎖 volatile

package com.utils.threads public class dl return instance public static void main string args 分析 加volatile的必要性 原因在於指令重排的存在,加入volatile可以禁止指令重排 當某乙個執行緒執...