為什麼要進行第一次判空//final類不可繼承
final public class single }}
return single;
}/**
* 私有建構函式,外部訪問不了
*/private single()
}
我們知道單例模式只有第一次執行create()方法的時候才會走synchronized 中的**,後面再次訪問的時候直接返回single 物件。如果說我們沒有第一次驗校,每乙個執行緒都要走synchronized 中的**,而每一次執行緒都要去拿到同步鎖才能執行。在多執行緒的情況下每乙個執行緒要拿到single 物件都要排隊等待同步鎖釋放。因此第一次驗校作用就是為了提高程式的效率。
為什麼要進行第二次判空
舉個例子:假如現在沒有第二次驗校,執行緒a執行到第一次驗校那裡,它判斷到single ==null。此時它的資源被執行緒b搶占了,b執行程式,進入同步**塊建立物件,然後釋放同步鎖,此時執行緒a又拿到了資源也拿到了同步鎖,然後執行同步**塊,因為之前執行緒a它判斷到single ==null,因此它會直接建立新的物件。所以就違反了我們設計的最終目的。
變數為什麼要加volatile關鍵字
請讀者自行了解volatile的原理。
優缺點、使用場景
雙重檢測單例模式
在多執行緒場景下,當乙個執行緒判斷instance為null時 他會新建乙個例項,那麼問題來了,當a執行緒發現物件例項為空時,準備 新建乙個例項,這時cpu輪詢到b執行緒,b執行緒也察覺物件例項為空,它也會新建乙個例項,這樣就破壞了單例模式。首先物件例項必須是全域性共享的,用volatile修飾,然...
單例模式之雙重檢查
在實現單例模式時,如果未考慮多執行緒的情況,就容易寫出下面的錯誤 public class singleton public singleton getinstance return uniquesingleton 在多執行緒的情況下,這樣寫可能會導致uniquesingleton有多個例項。比如下...
單例模式的雙重檢查
單例模式 public class singleton public static singleton getinstance return uniqueinstance 其中有兩次判斷是否為空的語句,第一次是為了提高效率,避免每次都要執行同步 塊,第二次判空,是為了避免多執行緒帶來的不安全,當兩個...