代码之家  ›  专栏  ›  技术社区  ›  Dushmantha

日志4J2LogManager.getLogger()线程安全吗?

  •  1
  • Dushmantha  · 技术社区  · 7 年前

    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 void calculate() 或者得到一个类锁,如下面所示,它可以正常工作。

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

    LogManager.getLogger() 线程不安全吗?还是我错过了什么?

    请注意,我尝试在没有 ExecutorService 使用 java.lang.Thread ),结果相同。

    • 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>
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   AreSo    7 年前

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

    例如,可以创建记录器字段:

    private final Logger logger = LogManager.getLogger();
    

    并在如下计算方法中使用:

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

    此外,每次调用calculate()时,它都会通过getLogger()方法为您节省一个记录器解析。

    希望有帮助。