[英]Is this a thread-safe implementation of Singleton?
我閱讀了Wikipeida的Singleton簡介,並編寫了此Singleton類。 可能存在線程安全問題嗎?
public class Engine {
private static volatile Engine instance = null;
private final Pipeline pipeline;
private Engine() {
pipeline = createEngine(SystemProperties.LANGUAGE);
}
public static Engine getInstance() {
if (instance == null) {
synchronized (Engine.class) {
if (instance == null) {
instance = new Engine();
}
}
}
return instance;
}
private Pipeline createEngine(Constants.Language langauge) {
Pipeline pipeline;
if (langauge == Constants.Language.Chinese) {
Properties props = IOUtils.readProperties("properties/chinese.properties");
pipeline = new Pipeline(props);
} else if (langauge == Constants.Language.English) {
Properties props = IOUtils.readProperties("properties/english.properties");
pipeline = new Pipeline(props);
} else {
throw new IllegalStateException("Unknow langauge not supported!");
}
return pipeline;
}
}
使用它的客戶端代碼:
private List<String> segment(String str) {
Engine ENGINE = Engine.getInstance();
List<String> tokens = new ArrayList<>();
...
try {
ENGINE.annotate(tokens);
}catch(Exception e){
log.warn("can't annotate this sentence:" + str);
}
...
return tokens;
}
是。 全局 :創建線程安全的單例類的更簡單方法是使全局訪問方法同步,一次只能有一個線程執行此方法。 由於與同步方法相關的成本,因此降低了性能。 為了避免每次額外的開銷,使用了雙重檢查的鎖定原理。 在這種方法中,在if條件(如何操作)中使用了同步塊,並進行了額外的檢查,以確保僅創建一個單例類實例。 另外請注意,單例可以通過反射來破壞。 為避免此問題,Joshua Bloch建議使用Enum來實現Singleton設計模式。 由於Java確保任何枚舉值在Java程序中僅實例化一次。
public enum EnumSingleton {
INSTANCE;
public static void doSomething(){
//do something
}
}
只是建議您完全理解單例模式,最好在GO4書中閱讀它,或者在約書亞·布洛赫(Joshua Bloch)有效的Java第2版中閱讀o'reilly優先設計模式。 有一章關於單例。
如Wikipedia文章所述,它在Java 5.0+中是線程安全的。
重要的是要知道, volatile
關鍵字實際上使其具有線程安全性。 Java允許其他線程使用部分構造類和線程與其他線程的變量的本地副本,它的工作-聯合-可能會導致在線程B一直以尚未完全初始化類的工作,從線程A的情況volatile
關鍵詞保證不會發生這種情況,而性能成本會稍微增加。
除此之外,與下面的簡單(且完全是線程安全的)實現相比,這種惰性初始化的方式過於復雜,后者依賴於類加載的保證:
public enum Singleton {
INSTANCE;
private Singleton() {
// initialization of Singleton
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.