全稱是double check lock
,即雙重鎖檢查,是在進入同步**塊之前和之後都進行一次檢查操作,之所以在進入同步**塊再檢查一次的原因是,有可能在外部檢查後,獲取同步鎖之前,當前持有鎖的執行緒,在釋放鎖之前已經改變了系統狀態,如下**:
volatile
int x =1;
// 第一次檢查
if(x ==1)
}}
如下時間線:
時間操作
x的值t1
執行緒a成功進入同步**塊,開始操作1t2
執行緒b判斷第乙個x == 1為true,但是阻塞1t3
執行緒a執行x == 2修改x的值為22t4
執行緒a進入同步**塊,再次判斷x == 1為false,結束
2如果是沒有再次x == 1
的檢查,則就產生程式錯誤了。
2.1:**
public
class
dclhungry
public
static dclhungry getinstance()
}}return instance;
}}
2.2:測試@test
public
void
testdclhungry()
,"執行緒!!!"
+ i)
.start()
;}}
多次執行:
例項初始化開始了
例項初始化結束了
執行緒!!!0-yudaosourcecode.dcltest.dclhungry@70107534
執行緒!!!1-yudaosourcecode.dcltest.dclhungry@70107534
執行緒!!!2-yudaosourcecode.dcltest.dclhungry@70107534
例項初始化開始了
例項初始化結束了
執行緒!!!0-yudaosourcecode.dcltest.dclhungry@227d344b
執行緒!!!2-yudaosourcecode.dcltest.dclhungry@227d344b
執行緒!!!1-yudaosourcecode.dcltest.dclhungry@227d344b
可以看到只建立了一次。我們可以將**修改為如下,即去掉第二次檢查:
public
static dclhungry getinstance()
}}return instance;
}
多次執行:
例項初始化開始了
例項初始化結束了
例項初始化開始了
執行緒!!!0-yudaosourcecode.dcltest.dclhungry@227d344b
執行緒!!!1-yudaosourcecode.dcltest.dclhungry@227d344b
例項初始化結束了
執行緒!!!2-yudaosourcecode.dcltest.dclhungry@17a4fb6d
以上結果初始化了2次
。
例項初始化開始了
例項初始化結束了
例項初始化開始了
例項初始化結束了
例項初始化開始了
例項初始化結束了
執行緒!!!1-yudaosourcecode.dcltest.dclhungry@1a4555f8
執行緒!!!0-yudaosourcecode.dcltest.dclhungry@227d344b
執行緒!!!2-yudaosourcecode.dcltest.dclhungry@17a4fb6d
以上結果初始化了3次
。 dcl單例模式
有時候我們需要對外呈現只有乙個物件,簡單來說就是講物件私有化,像資料那樣,只能通過get方法得到。這裡使用doublechecking來進行該操作,即在get方法裡面加入兩個判斷該物件是否為空,同時為了避免指令重排導致執行緒獲得空物件,加入volatile,而且私有化構造器。public class...
DCL單例模式
單例模式 外部不能new物件,類的內部有且只有乙個物件,僅僅用乙個靜態方法與外界進行互動。public class doublecheckedlocking 外部只能通過這個get方法和此物件進行交流 public static doublecheckedlocking getinstance 繫結...
懶漢單例模式
單例設計模式 懶漢單例模式 能夠保證在只有用它的時候才建立它的物件。目前還不能保證乙個類在記憶體中只有乙個物件。懶漢單例模式設計步驟 1 私有化建構函式 2 生命本類的引用型別變數,但是不要建立物件 3 提供公共的靜態方法獲取本類的物件,獲取之前先判斷是否已經建立了本類的物件,如果已經建立了,那麼直...