gpt4 book ai didi

java - log4j2 LogManager.getLogger() 是线程安全的吗?

转载 作者:行者123 更新时间:2023-11-30 06:02:41 27 4
gpt4 key购买 nike

当我执行以下代码时,日志事件仅记录一次。我正在使用 log4j2 记录器。但是当我使用 java.util.logger 时,所有 3 个日志事件均已成功发布。

   public class TestLoggingMDC
{
public static void main( String[] args ) throws InterruptedException
{
System.setProperty( "log4j.configurationFile", "log4j2.xml" );//set path here to log4j2 config file

ExecutorService executor = Executors.newFixedThreadPool( 3 );
TestLoggingMDC testLoggingMDC = new TestLoggingMDC();

for ( int i = 0; i < 3; i++ )
{
Runnable runnableTask = testLoggingMDC::calculate;
executor.execute( runnableTask );
}

executor.awaitTermination( 5, TimeUnit.SECONDS );

}

public void calculate()
{
//java.util.logging.Logger.getLogger( "testMDC" ).info( "total is ..." );//this works. log 3 time
LogManager.getLogger( ).info( "total is ..." );//this does not

}

}

当我同步计算方法 public synchronized voidcalculate() 或获取类锁时,如下所示,它会按预期工作。

public  void calculate()
{
synchronized ( LogManager.class )
{
LogManager.getLogger().info( "total is ..." );
}

}

log4j2是线程安全的,但似乎LogManager.getLogger()不是线程安全的?或者我错过了什么?

请注意,我尝试在没有 ExecutorService 的情况下执行线程(使用 java.lang.Thread),结果是相同的。

  • log4j2 版本 2.7
  • IntelliJ Idea 2018.1.5

log4j2 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss,SSS} [%t] %-5p %c{36} - %m%n"/>
</Console>
<File name="fileAppender" fileName="out/MDCTest.log">
<PatternLayout>
<Pattern>%X{id} %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Logger name="testMDC" level="ALL">
<AppenderRef ref="fileAppender"/>
</Logger>
</Loggers>
</Configuration>

最佳答案

它不是线程安全的。 Logger 不记录初始消息,因为它默认配置为 ERROR 级别,然后重新配置为 INFO。您可以通过将 calculate() 中的日志记录方法从 info() 更改为 error() 来检查 - 您将收到全部 3 条消息。

要修复此问题,需要在干扰线程之前重新配置记录器。例如,您可以创建一个记录器字段:

private final Logger logger = LogManager.getLogger();

并在这样的计算方法中使用:

public void calculate() {
loger.info( "total is ..." );
}

此外,每次调用calculate()时,它都会通过getLogger()方法为您节省记录器分辨率。

希望有帮助。

关于java - log4j2 LogManager.getLogger() 是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51965928/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com