雙重檢查加鎖機制


先舉典型的例子,單例模式。

View Code
 1 public sealed class Singleton
2 {
3 private Singleton(){}
4 private static Singleton instance = null;
5 private static object syncRoot = new object();
6
7 public static Singleton Instance
8 {
9 get
10 {
11 if (instance == null)
12 {
13 lock (syncRoot)
14 {
15 if (instance == null)
16 {
17 instance = new Singleton();
18 }
19 }
20 }
21 return instance;
22 }
23 }
24 }

這里簡單說一下,lock(syncRoot) 獲取對象syncRoot的互斥鎖,可以簡單理解為,當多個線程同時執行到lock的時候,大家排隊,一個一個地進行。C#中的lock對應於Java中的synchronized。這里在11行與15行進行了重復檢查,有些人認為是沒有必要的。因為下面的代碼是等效的。

 

View Code
 1 public sealed class Singleton
2 {
3 private Singleton(){}
4 private static Singleton instance = null;
5 private static object syncRoot = new object();
6
7 public static Singleton Instance
8 {
9 get
10 {
11 lock (syncRoot)
12 {
13 if (instance == null)
14 {
15 instance = new Singleton();
16 }
17 }
18 return instance;
19 }
20 }
21 }

那么我們就結合實際的情況來分析一下二者的區別,為了說明方便,以上兩種情況分別簡稱為 “雙重檢查鎖”和“單重檢查鎖”。 


 1、第一次訪問Instance,同時來了10個線程。對於雙重檢查鎖,instance為null,10個線程在這里lock處排隊;對於單重檢查鎖,10個線程在lock處排隊。二者是相同的。

2、第二次、第三次。。。訪問Instance,同時來了10個線程。對於雙重檢查鎖,instance不為null,10個線程不用排隊,直接返回instance;對於單重檢查鎖,10個線程,還必須要在lock處排隊。

雙重檢查鎖的優點體現出來了:避免了不必要的排隊現象。也就是說,雙重檢查鎖的第一重檢查,是很必要的,它來保證不必要的排隊。

舉個例子說明,病人到醫院看病,第一次去的時候,都要排隊去辦病歷本。以后再去的時候,如果有病歷本,就不用再排隊去辦了。 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM