Java 正在停止log4J AsyncAppender的线程

Java 正在停止log4J AsyncAppender的线程,java,thread-safety,log4j,Java,Thread Safety,Log4j,我在应用程序中使用Log4J AsyncAppender,我想知道,当我的应用程序完成时,AsyncAppender的线程会发生什么?我应该手动终止线程,还是可以忘记它,退出应用程序而不用担心某些日志消息会丢失?如果AsyncAppender是在应用程序中运行的线程,那么当您关闭应用程序时,它将被关闭(应用程序指的是jvm的当前实例)。我不知道这是否是您的问题,但是查看AsyncAppender的源代码(第112-117行)来处理事件的写入,作者希望您在appender上显式调用close(),

我在应用程序中使用Log4J AsyncAppender,我想知道,当我的应用程序完成时,AsyncAppender的线程会发生什么?我应该手动终止线程,还是可以忘记它,退出应用程序而不用担心某些日志消息会丢失?

如果AsyncAppender是在应用程序中运行的线程,那么当您关闭应用程序时,它将被关闭(应用程序指的是jvm的当前实例)。我不知道这是否是您的问题,但是查看AsyncAppender的源代码(第112-117行)来处理事件的写入,作者希望您在appender上显式调用
close()
,以确保在JVM关闭之前写出所有排队的消息:

dispatcher = new Thread(new Dispatcher(this, buffer, discardMap, appenders));

// It is the user's responsibility to close appenders before
// exiting.
dispatcher.setDaemon(true);

通过将线程设置为守护进程,这意味着一旦应用程序的核心退出,JVM将无法继续运行。但是,这也意味着,如果应用程序在未通知附加程序的情况下关闭,队列中的任何消息都将丢失。

如果在JVM关闭之前调用
LogManager.shutdown()
,它将继续运行,直到刷新附加程序为止。请注意,这仅对log4j 1.x是必需的。我从文档中了解到Log4j 2会自动注册一个关机钩子来处理这个问题。

这不是很准确-一个非守护进程线程会继续运行,并且会阻止JVM关机。好的,我对答案进行了编辑,以使其更加清晰和准确。如果我使用xml配置log4J,并且使用slf4J和spring,如何访问appender对象?是否有某种方法可以在xml中配置log4J,以便在应用程序关闭时自动调用appender的close方法?这是一个很好的问题,因为这似乎是他们API中非常令人困惑的一部分(并且使设计决策需要调用
close()
令人困惑)。我不确定访问appender的最佳方式是什么,但您可以尝试类似于
Logger.getLogger(名称).getAllAppenders()
Logger.getLogger(名称).getAppender(名称)
Logger.getRootLogger().getAllAppenders()
。我会将其添加到JVM关闭挂钩中。这不太好,因为它需要你的应用程序代码知道日志配置,这是我在关闭一个使用asyncAppender和RollingLandMacAccessFile的短时间应用程序时唯一能够获取所有日志的方法,而无需立即刷新,谢谢!