今天和同事聊起了單例模式的執行緒安全,我說如果不做任何措施,單例模式在多執行緒下是不安全的,得到的「單例」實際上並不是單例。但是為什麼不是單例呢?由此我上網查了一下,在使用單例模式時,一定要注意執行緒安全問題,之前的寫法沒有任何問題。如下:
package com.xhz.singleton;
/** * 單例
* @author xhz
*/public class singleton
public static synchronized singleton getinstance()
return instance;
}}
問題就在於,synchronized對整個方法加鎖,形成同步機制,這樣雖然解決了單例模式的執行緒安全問題,但是卻產生另外乙個問題效能問題,對方法加鎖這個顆粒度有點大,我們稍微改進一下。如下:
package com.xhz.singleton;
/** * 單例
* @author xhz
*/public class singleton
public static singleton getinstance() }}
return instance;
}}
利用雙重鎖的方式這樣顆粒度變小了,但還是利用同步的方式來解決資源共享問題。其實這上面兩種寫法稱之為「懶載入」,即在用到的時候再來例項化。
我們再次修改**,如下。
package com.xhz.singleton;
/** * 單例
* * @author xhz
*/public class singleton
public static singleton getinstance()
}
我們不利用執行緒同步的方式,而是在類被載入的時候就生成乙個例項物件。這稱之為「勤載入」,這個帶來的問題就是,不管這個單例有沒有用到都會一直存在。
兩者都有其優缺點,但相對於利用執行緒同步的方式來解決執行緒安全問題,「勤載入」會是乙個較為明智的選擇。
之所以懶載入不採取任何措施造成的執行緒不安全問題,是因為在程式中出現了「競態條件(race condition)」,由於不恰當的執行時序而出現不正確的結果。最常見的競態條件型別就是「先檢查後執行(check-then-act)」操作,即通過乙個可能失效的觀測結果來決定下一步的動作。
單例模式的執行緒安全問題
單例會帶來什麼問題?如果多個執行緒同時呼叫這個例項,會有執行緒安全的問題 單例一般用在什麼地方?單例的目的是為了保證執行時只有唯一的乙個例項,最常用的地方比如拿到資料庫的連線,或者spring的中建立beanfactory操作,而這些操作都是呼叫他們的方法來執行某個特定的動作。首先先來認識下兩種模式...
單例模式的執行緒安全問題
大家都知道單例模式有兩種,分別是懶漢式 餓漢式。但是對於餓漢式,由於判斷例項為null與建立物件的操作並不是乙個原子性操作,故在 普通的懶漢式單例 非執行緒安全問題 1 2 created by ywb 3 4public class singleton 910 public static sing...
單例模式及執行緒安全問題
單例模式是為確保乙個類只有乙個例項,並為整個系統提供乙個全域性訪問點的一種模式方法。從概念中體現出了單例的一些特點 1 在任何情況下,單例類永遠只有乙個例項存在 2 單例需要有能力為整個系統提供這一唯一例項 下面是實現 package org.mlinge.s02 public class mysi...