当您定义一个外部标志时,应该在设置 该volatile
标志的同时轮询该线程并退出该线程。否则,该线程可能永远不会看到其他线程所做的更改。
但是,标准API中已经有类似的功能-
它称为
interrupt()方法和
Thread.currentThread().isInterrupted()。无需重复已经存在的逻辑。请参阅:停止特定的Java线程。
话虽这么说,调用
interrupt()每个线程也是一个坏主意,因为不能保证所有线程都会对此做出响应。检查您的异常情况后,我发现以下线程未正确清理:
com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread-#0
-关闭C3P0数据源。由于您使用的是Spring,因此只需添加destroy-method="close"
。我们已经完成了这个线程。File Reaper
-据我所知,该线程是由FileCleaningTracker创建的。FileCleaningTracker.exitWhenFinished()
关闭应用程序时(或者不再需要该类,我从没使用过)时,需要显式调用,或者让Spring进行此操作(请参见上文)。某些第三方库可能会使用它并且无法正确关闭-这意味着它存在错误。pool-1-thread-22
-这是Executors
Utility内部创建的线程之一ExecutorService
。确保shutdown()
在关闭过程中调用应用程序中的每个此类池。org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2
-Quartz工作线程(实际运行作业的线程)。SchedulerFactoryBean
自动为您关闭调度程序,我认为Tomcat错误在这里,我也经常看到此错误。不过貌似设置SchedulerFactoryBean.waitForJobsToCompleteOnShutdown
来true
解决这个问题。com.iteezy.shared.domain.DirEntry.data
-我不确定这一点。它是您自己的线程需要在关闭时中断,还是H2数据库线程(?)需要检查其堆栈以猜测其来源。
底线是:不要仅仅杀死所有移动的内容(实际上,Tomcat在发出此警告之后会为您执行此操作),而是确定线程的来源,并使用特定
close()于框架/库的方法来进行进一步清理。要温柔。



