簡體   English   中英

這是Singleton的線程安全實現嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM