线程安全的单例和内部类解决方案

时间:2013-05-11 21:37:53

标签: java thread-safety singleton

这就是我总是创建一个线程安全的单例,以便在多线程应用程序中使用它。

public class Logger {

    private Logger() {}

    private static Logger instance = new Logger();

    public static Logger getInstance() {
        return instance;
    }

    public void log(String s) {
        // Log here
    }
}

今天我正在学习接受我的Java认证,在书中我发现了另一个解决方案:

public class Logger {

    private Logger() {}

    private static Logger instance;

    private static class LoggerHolder {
        public static Logger logger = new Logger();
    }

    public static Logger getInstance() {
        return LoggerHolder.logger;
    }

    public void log(String s) {
        // Log here
    }
}

他们没有提到另一个。

什么更好?两种解决方案之间有什么区别?

2 个答案:

答案 0 :(得分:1)

第二个示例仅因为您访问该类而不太可能创建实例。相反,你必须访问内部类。这种程度的偏执对JDK库设计师来说是有意义的,但是在一个更受控制的代码库中,它已经超越了顶级的恕我直言。

我更喜欢简单,而是使用它

public enum MyLogger {
    INSTANCE;

    public void log(String s) {
       // log here
    }
}

我强烈反对创建一个名为Logger的类。已经有足够的混淆了这个类的许多实现,包括一个内置。

答案 1 :(得分:0)

第二个是懒惰的。如果,通过一些奇迹,程序加载类但从不调用getInstance(),将不会创建可能是一个昂贵的对象创建的记录器实例。

坦率地说,如果确实需要一个单例(并且使用依赖注入框架,它们几乎总是不需要),我更喜欢第一个更容易理解的解决方案。如果有的话,我很少看到一个单独的类,它的类已加载但从未在实际代码中使用过。