Java 线程安全的单例和内部类解决方案
为了在多线程应用程序中使用它,我总是这样创建线程安全的单例Java 线程安全的单例和内部类解决方案,java,thread-safety,singleton,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
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
}
}
他们没有提到另一个
什么更好?这两种解决方案的区别是什么?第二个示例不太可能仅仅因为访问了类就创建实例。相反,您必须访问内部类。这种程度的偏执对JDK库设计人员来说是有意义的,但在一个更受控制的代码库中,它超出了IMHO的范围 我更喜欢简单,我会用这个来代替
public enum MyLogger {
INSTANCE;
public void log(String s) {
// log here
}
}
我强烈建议不要创建一个名为
Logger
的类,该类的许多实现已经存在足够的混乱,包括一个内置的。第二个是懒惰的。如果,奇迹般地,程序加载了类,但从未调用getInstance()
,那么记录器实例将不会被创建,因为它可能是一个昂贵的对象
坦白地说,如果真的需要一个单例(并且依赖注入框架几乎总是不需要),我更喜欢第一个解决方案,它更容易理解。我很少(如果有过的话)看到一个类已加载但从未在实际代码中使用的单例