我使用procrun创建了一个服务,它通过反射启动某些jar。当服务启动时,它启动一个线程,其余的执行发生在该线程中。然后每个插件加载自己的线程并在那里执行。
在服务停止期间,我调用了插件的停止方法。这些方法已经返回,我创建的任何线程都已终止插件。但即便如此,以下线程仍在运行。
INFO: Thread No:0 = Timer-0
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:1 = WebSocketWorker-14
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:2 = WebSocketWorker-15
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:3 = WebSocketWorker-16
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:4 = WebSocketWorker-17
Jan 13, 2016 10:49:58 AM com.kube.desktop.KubeSdkMain stop
INFO: Thread No:5 = WebsocketSelector18
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:6 = AWT-EventQueue-0
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:7 = DestroyJavaVM
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
INFO: Thread No:8 = Thread-11
Jan 13, 2016 10:49:58 AM com.test.desktop.SdkMain stop
以下是我打印这些线程的方法。
ThreadGroup currentGroup = Thread.currentThread().getThreadGroup();
int noThreads = currentGroup.activeCount();
Thread[] lstThreads = new Thread[noThreads];
currentGroup.enumerate(lstThreads);
for (int i = 0; i < noThreads; i++)
LOGGER.log(Level.INFO, "Thread No:" + i + " = " + lstThreads[i].getName());
由于这些线程,当我停止服务时,它需要永远然后超时。但是当我调用System.exit(0)时,服务会很快停止。我该怎么做才能摆脱这些线程?当我通过反射启动jar时,是否为每个插件创建了单独的线程?如果是这样,他们可以吗?请指教。
答案 0 :(得分:0)
看起来插件是他们自己启动的线程(&#34; INFO:线程号:1 = WebSocketWorker-14&#34; - &gt;套接字通常应该放在单独的线程中)如果你不会被关闭杀死初始线程。你必须强制执行你的插件来杀死他们关闭时启动的所有线程,以确保他们不会留下任何东西。 &#34;一些插件不能很好地清理他们创造的任何东西。它只是草率的编程。&#34; - bayou.io在那里描述它非常好。
调用System.exit()只会终止进程,这意味着它也会终止进程创建的所有线程。
另一种方法是手动迭代所有正在运行的线程,检查它是否是主线程,如果没有继续杀死它。您可以使用
在可迭代集中获取所有正在运行的线程Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
您可以使用
获取当前正在运行的线程Thread currentThread = Thread.currentThread();
这仍然是你不想这样做的方式,如果插件决定留下东西而不仅仅是这样做,那么它更像是一种清理方式。插件自己应该在线程被禁用时关闭线程,但如果他们不这样做,你可以使用上面的方法手动清理它。