3

我使用 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 时,是否为每个插件创建了单独的线程?如果是这样,这些可能是他们吗?请指教。

4

1 回答 1

0

看起来插件本身就是启动线程(“INFO:Thread No:1 = WebSocketWorker-14”->套接字通常应该放在单独的线程中),如果你杀死启动线程,这些线程不会被关闭。你必须强制你的插件杀死它们在关闭时启动的所有线程,以确保它们不会留下任何东西。“有些插件不能很好地清理他们创建的任何东西。这只是草率的编程。” -bayou.io 在那里描述得非常好。

调用 System.exit() 只会杀死进程,这意味着它也会杀死进程创建的所有线程。

另一种方法是手动迭代所有正在运行的线程,检查它是否是主线程,如果不是则继续杀死它。您可以使用可迭代集中获取所有正在运行的线程

Set<Thread> threadSet = Thread.getAllStackTraces().keySet();

你可以使用你当前正在运行的线程

Thread currentThread = Thread.currentThread();

这仍然是您不想这样做的方式,如果插件决定留下东西而不是那样做,它更像是一种清理方式。插件本身应该在线程被禁用时关闭线程,但如果他们不这样做,您可以使用上述方法手动清理它。

于 2016-01-13T09:28:40.110 回答