繁体   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