Java雙重檢查鎖的錯誤

2021-08-21 19:24:22 字數 937 閱讀 8203

1.錯誤的雙重檢查鎖實現

public class doublecheckedlocking  // 8

} // 9

return instance; // 10

} // 11

}

前面的雙重檢查鎖定示例**的第7行(instance=new singleton();)建立了乙個物件。這一行**可以分解為如下的3行偽**。

memory = allocate();  // 1:分配物件的記憶體空間

ctorinstance(memory); // 2:初始化物件

2.新增volatile關鍵字

public class doublecheckedlocking  // 8

} // 9

return instance; // 10

} // 11

}

為了解決上面的問題,只要在instance引用上新增volatile關鍵字即可。原因是:

memory = allocate();  // 1:分配物件的記憶體空間

ctorinstance(memory); // 2:初始化物件

instance = memory;  // 3:設定instance指向剛分配的記憶體位址(此時instance 是volatile型別的引用,根據volatile特性,當第二個操作是volatile寫時,不管第乙個操作是什麼,都不能重排序,所以這三個操作都會按照順序執行)

此時instance 是volatile型別的引用,根據volatile特性(可以參考《volatile的特性》一文),當第二個操作是volatile寫時,不管第乙個操作是什麼,都不能重排序,所以這三個操作都會按照順序執行,volatile關鍵字禁止了重排序,保證了物件一定是被初始化過後,才被賦值給instance引用的。

雙重檢查鎖

雙重檢查鎖 簡單來說,就是在併發場景下,實現單列模式時,為解決單列模式的特性,以及效能的開銷,在例項化時先判斷物件是否已經初始化,再決定是否加鎖,同時再進行物件二次判空驗證。如以下示例 所示 注意 示例 中 volatile 關鍵字是解決由於編譯優化帶來的有序性問題可能導致程式的執行順序並不是我們所...

單例模式 雙重檢查鎖

單例模式分為餓漢式和懶漢式。餓漢式是事先分配記憶體,提前建立。這樣的方式為到位占用資源,當這種比較多時,會占用很多記憶體。懶漢式是在被呼叫的時候進行。這種在併發時又會導致問題。比較穩妥的辦法是在懶漢式的基礎上加上鎖,然後進行雙重檢查,這種springioc容器式單例也是用這種雙重檢查來避免執行緒衝突...

雙重檢查鎖模式導致空指標

今天遇到乙個問題 莫名奇妙報了個空指標,後來發現原來單例模式在高併發下引起的 雙重檢查鎖模式的一般實現 雙重檢查鎖模式解決了單例 效能 執行緒安全問題,但是這種寫法同樣存在問題 在多執行緒的情況下,可能會出現空指標問題,出現問題的原因是jvm在例項化物件的時候會進行優化和指令重排序操作。public...