Java 如何消除log4j消息中关于“的警告”;“没有附加者”;在多线程应用程序关闭时?

Java 如何消除log4j消息中关于“的警告”;“没有附加者”;在多线程应用程序关闭时?,java,multithreading,log4j,application-shutdown,Java,Multithreading,Log4j,Application Shutdown,我有一个多线程程序,基本上有两个无限循环线程加上一些GUI(Swing)。我的两个无限循环线程有自己的log4j记录器,如下所示: static final Category LOG = Category.getInstance(RReceiver.class); 在GUI中检测到退出键时,我只执行System.exit(0): 控制台中的效果如下: static final Category LOG = Category.getInstance(RReceiver.class

我有一个多线程程序,基本上有两个无限循环线程加上一些GUI(Swing)。我的两个无限循环线程有自己的log4j记录器,如下所示:

    static final Category LOG = Category.getInstance(RReceiver.class);
在GUI中检测到退出键时,我只执行System.exit(0):

控制台中的效果如下:

    static final Category LOG = Category.getInstance(RReceiver.class);
调试13:07:00940[接收器](RReceiver.java:93)-获得响应len:38
调试13:07:01044[接收器](RReceiver.java:93)-获得响应len:38
调试13:07:01045[接收器](RReceiver.java:93)-新状态dev 4
log4j:WARN找不到记录器的附加器(com.normantech.ibcol.radiobox.RReceiver)
log4j:警告请正确初始化log4j系统

警告并不总是出现。我怀疑有错误的去初始化顺序,但无法理解。
为什么会这样?我已尝试使用LogManager.shutdown();但这没用。我试图很好地完成无限循环,但这不是最好的解决方案,因为我需要添加一些额外的线程。sleep(x),尝试了不同的x,但实际上不确定这是否有帮助。

核心问题是,调用System.exit()会杀死线程,而不是让它们完全关闭。这意味着,它们可能会在其他一切都关闭后但JVM实际结束进程之前保持非常短暂的运行,如果在此期间使用任何共享状态(例如日志系统),则可能处于不一致或中断状态,因为它可能已关闭。这不是一个好的做法(请参阅)

解决这一问题的方法是在关闭共享资源(日志系统)之前适当关闭线程。不要只调用system.exit(),而是告诉每个线程该停止了,并等待他们停止。最干净的方法是让他们检查每个循环上运行的
布尔值,并在希望循环停止时将该布尔值设置为false。然后,您可以等待线程注意到这个布尔值,并通过调用给定线程实例上的thread.join()终止,或者在完成时让线程设置一些
finished
boolean(最好将这两个布尔值都标记为volatile)

如果循环的每次迭代都需要一些时间,或者包含
wait()
sleep()
调用,那么您应该在循环期间更频繁地检查正在运行的布尔值,或者使用
Thread.interrupt()


一旦完成此操作,并且您确定每个其他线程都已停止,您就可以调用
LogManager.shutdown()
并实际终止您的进程。

好的,这是我的错:先关闭线程,然后关闭LogManager,而不是其他。现在工作得很好!