我维护一个库,启动一个守护程序线程在后台工作.在常规Java和Android应用程序中,此线程启动一次并在该进程的生命周期内运行.它永远不会退出,这没关系.
当我的库包含在支持应用程序卸载的应用程序容器(例如Tomcat)中时,应用程序永远不会卸载.我正在运行的线程拥有对其自己的类的强引用,并阻止整个应用程序被卸载.我的库的用户不能热插拔他们的应用程序而不会每次泄漏内存.
当应用程序容器希望卸载我的库时,获取信号的最佳方法是什么?
这是一个小型库,不依赖于应用程序容器API.它不知道它正在运行哪个应用程序容器而且它不想要!
这个库启动一个线程的事实是一个实现细节.库的最终用户不应该知道线程正在启动,并且关闭它不是他们的责任.
最好的办法是提供一种清理库的方法.最终用户必须调用它(可能基于处理容器中的应用程序生命周期).Listener当在兼容的servlet容器(例如,Tomcat)中使用它时,您也可以提供这些情况,但您的最终用户仍然必须知道并将描述符放在web.xml中.
唯一的另一种选择是你的最终用户必须创建一个能够让线程死掉的监听器.我不得不在几个场合这样做,这并不漂亮.它通常涉及使用反射来获取线程并将其杀死.当然,ThreadDeath异常由一些库处理,并且线程拒绝死亡.然后,这需要更多地使用反射来清理混乱.
如果您给他们一个简单的方法来清理库,那么您的最终用户会好得多.它很糟糕,他们必须了解您的实现细节,但他们已经这样做,因为您要保持应用程序不被卸载.
难道你不能确定应用程序在最后x分钟/秒内是否使用了你的lib,如果没有则关闭线程?下次使用时重启吗?这样的java.util.concurrent.ThreadPoolExecutor作品.