日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
雙重檢查鎖定失敗可能性

雙重檢查鎖定在延遲初始化的單例模式中見得比較多(單例模式實(shí)現(xiàn)方式很多,這里為說明雙重檢查鎖定問題,只選取這一種方式),先來看一個(gè)版本:

成都創(chuàng)新互聯(lián)公司專注于臨縣網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供臨縣營(yíng)銷型網(wǎng)站建設(shè),臨縣網(wǎng)站制作、臨縣網(wǎng)頁設(shè)計(jì)、臨縣網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造臨縣網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供臨縣網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。

 
 
 
  1. public class Singleton {
  2.     private static Singleton instance = null;
  3.     private Singleton(){}
  4.     
  5.     public static Singleton  getInstance() {
  6.        if(instance == null) {
  7.            instance = new Singleton();
  8.        }
  9.        return instance;
  10.     }
  11. }

上面是最原始的模式,一眼就可以看出,在多線程環(huán)境下,可能會(huì)產(chǎn)生多個(gè)Singleton實(shí)例,于是有了其同步的版本:

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

在這個(gè)版本中,每次調(diào)用getInstance都需要取得Singleton.class上的鎖,然而該鎖只是在開始構(gòu)建Singleton 對(duì)象的時(shí)候才是必要的,后續(xù)的多線程訪問,效率會(huì)降低,于是有了接下來的版本:

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

很好的想法!不幸的是,該方案也未能解決問題之根本:

原因在于:初始化Singleton 和 將對(duì)象地址寫到instance字段 的順序是不確定的。在某個(gè)線程new Singleton()時(shí),在構(gòu)造方法被調(diào)用之前,就為該對(duì)象分配了內(nèi)存空間并將對(duì)象的字段設(shè)置為默認(rèn)值。此時(shí)就可以將分配的內(nèi)存地址賦值給instance字段了,然而該對(duì)象可能還沒有初始化;此時(shí)若另外一個(gè)線程來調(diào)用getInstance,取到的就是狀態(tài)不正確的對(duì)象。

鑒于以上原因,有人可能提出下列解決方案:

 
 
 
  1. public class Singleton {
  2.     private static Singleton instance = null;
  3.     private Singleton(){}
  4.     
  5.     public static Singleton getInstance() {
  6.        if(instance == null) {
  7.            Singleton temp;
  8.            synchronized(Singleton.class) {
  9.               temp = instance;
  10.               if(temp == null) {
  11.                   synchronized(Singleton.class) {
  12.                      temp = new Singleton();
  13.                   }
  14.                   instance = temp;
  15.               }
  16.            }
  17.        }
  18.        return instance;
  19.     }
  20. }

該方案將Singleton對(duì)象的構(gòu)造置于最里面的同步塊,這種思想是在退出該同步塊時(shí)設(shè)置一個(gè)內(nèi)存屏障,以阻止初始化Singleton 和 將對(duì)象地址寫到instance字段 的重新排序。

不幸的是,這種想法也是錯(cuò)誤的,同步的規(guī)則不是這樣的。退出監(jiān)視器(退出同步)的規(guī)則是:所以在退出監(jiān)視器前面的動(dòng)作都必須在釋放監(jiān)視器之前完成。然而,并沒有規(guī)定說退出監(jiān)視器之后的動(dòng)作不能放到退出監(jiān)視器之前完成。也就是說同步塊里的代碼必須在退出同步時(shí)完成,而同步塊后面的代碼則可以被編譯器或運(yùn)行時(shí)環(huán)境移到同步塊中執(zhí)行。

編譯器可以合法的,也是合理的,將instance = temp移動(dòng)到最里層的同步塊內(nèi),這樣就出現(xiàn)了上個(gè)版本同樣的問題。

在JDK1.5及其后續(xù)版本中,擴(kuò)充了volatile語義,系統(tǒng)將不允許對(duì) 寫入一個(gè)volatile變量的操作與其之前的任何讀寫操作 重新排序,也不允許將 讀取一個(gè)volatile變量的操作與其之后的任何讀寫操作 重新排序。

在jdk1.5及其后的版本中,可以將instance 設(shè)置成volatile以讓雙重檢查鎖定生效,如下:

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

需要注意的是:在JDK1.4以及之前的版本中,該方式仍然有問題。


網(wǎng)站名稱:雙重檢查鎖定失敗可能性
轉(zhuǎn)載源于:http://www.5511xx.com/article/dpocpgg.html