單例模式雙重檢驗鎖的判斷是否為null的意義


關於雙重檢驗鎖首先簡單來看一個小例子:

 1 public class Singleton{
 2     private static Singleton instance = null;
 3     private Singleton(){}
 4 
 5     public static Singleton getInstance(){
 6         if (instance == null) {//e1
 7             synchronized(Singleton.class){
 8                 if (instance == null) {//e2
 9                     instance = new Singleton();
10                 }
11             }
12         }
13         return instance;
14     }
15 }

雙重檢驗鎖是對同步塊加鎖的方法。為什么會稱為雙重檢驗,因為有兩次對 instance == null的檢查,一次中同步塊中一次中同步塊外部。

對於兩次instance的是否為空的判斷解釋:

1.為何在synchronization外面的判斷?

       為了提高性能!如果拿掉這次的判斷那么在行的時候就會直接的運行synchronization,所以這會使每個getInstance()都會得到一個靜態內部鎖,這樣的話鎖的獲得以及釋放的開銷(包括上下文切換,內存同步等)都不可避免,降低了效率。所以在synchronization前面再加一次判斷是否為空,則會大大降低synchronization塊的執行次數。

2.為何在synchronization內部還要執行一次呢?

因為可能會有多個線程一起進入同步塊外的 if,如果在同步塊內不進行二次檢驗的話就會生成多個實例了。

 

PS:雙重檢驗情況下,保存實例的唯一的靜態變量要用volatile修飾,否則由於線程安全原因,一個類仍然有會生成多個實例。


免責聲明!

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



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