SLF4J是否是线程安全的?

我可能有一个Dog类,它有一个跨多个线程共享的实例。 我计划将SLF4J用于所有日志记录:

 public class Dog { private Logger logger = LoggerFactory.getLogger(Dog.class); // ...etc. } 

我的logger实例线程是否安全? 为什么/为什么不呢?

当然,每个人都认为 Logger将是线程安全的。 但是你需要查看外观背后的实现类的代码/ javadoc来绝对确定。

具体实现:

  • Log4j 1.2是线程安全的
  • java.util.logging.Logger是线程安全的 (搜索“multithreading安全”)
  • Logback是线程安全的

(显然,这些是相应代码设计为线程安全的声明。总是存在错误。例如, Log4j 2跟踪器中当前存在一些开放的线程安全错误,尽管它看起来不像这些错误会直接影响您的示例代码。)

总结: LoggerFactory.getLogger(Class) “缓存”基于类的Logger实例。 因此,如果我两次调用LoggerFactory.getLogger(Dog.class) ,我将在内存中获得对同一对象的2个引用。 这意味着如果2个线程实例化一个Dog ,它们将获得相同(共享)Dog Logger实例。

所以SLF4J API 不是线程安全的。 这完全取决于您选择的绑定。 看起来常见的绑定(log4j,JUL和logback)是线程安全的,所以即使多个线程可以访问同一个Dog Logger ,log4j / JUL / logback记录器绑定也是线程安全的,所以你没有问题。

例证:如果您正在制作自己的SLF4J绑定,请使所有Logger impl方法synchronized ,或以不同方式解决线程安全问题(提供ThreadLocal等)。