我可能有一个Dog
类,它有一个跨多个线程共享的实例。我计划将SLF4J用于所有日志记录:
public class Dog {
private Logger logger = LoggerFactory.getLogger(Dog.class);
// ...etc.
}
我的logger
实例线程是否安全?为什么/为什么不呢?
答案 0 :(得分:37)
当然,每个人都假定 Logger
将是线程安全的。但是您需要查看Facade背后的实现类的代码/ javadoc,以确保绝对。
具体实施:
(显然,这些是相应的代码设计到线程安全的声明。总是有bug。例如,当前几个打开the Log4j 2 tracker中的线程安全错误,但似乎这些错误不会直接影响您的示例代码。)
答案 1 :(得分:-10)
总之: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
等)。