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
等)。