在多线程应用程序中停止线程

时间:2016-01-13 05:39:34

标签: java multithreading service thread-safety procrun

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

1 个答案:

答案 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();

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