如何查找和停止所有当前运行的线程?

我有一个multithreadingjava项目,我想添加一个方法stop()来停止所有正在运行的线程。 问题是这个项目是由其他人开发的,我不熟悉它如何实现多个线程。

我所知道的是,一旦项目开始,就会调用许multithreading并且它们会永远运行。 有没有办法找到所有正在运行的线程并阻止它们? 我搜索了很多,并找到了如何获取正在运行的线程列表:

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

下一步要做什么来阻止所有正在运行的线程?

我想要停止这些线程的原因是我需要将此项目作为捆绑包部署到OSGi容器。 捆绑包启动后,多个线程将永远运行。 所以我需要实现一个destroy()方法来阻止所有线程来控制bundle生命周期。

怎么样

 for (Thread t : Thread.getAllStackTraces().keySet()) { if (t.getState()==Thread.State.RUNNABLE) t.interrupt(); } for (Thread t : Thread.getAllStackTraces().keySet()) { if (t.getState()==Thread.State.RUNNABLE) t.stop(); } 

这是一个危险的想法。 Thread.stop()的Javadoc解释说:

这种方法本质上是不安全的。 使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeathexception向上传播的自然结果)。 如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为。 stop的许多用法应该由代码修改,该代码只是修改某个变量以指示目标线程应该停止运行。 目标线程应定期检查此变量,如果变量指示它将停止运行,则以有序的方式从其run方法返回。 如果目标线程等待很长时间(例如,在条件变量上),则应使用中断方法来中断等待。

从根本上说,线程需要构建和设计以安全终止,不可能安全地杀死任意线程。 一个相当标准的模式实现如下:

 public abstract class StoppableRunnable implements Runnable { private volatile boolean stopWork;; private boolean done; public final void run() { setup(); while(!stopWork && !done) { doUnitOfWork(); } cleanup(); } /** * Safely instructs this thread to stop working, * letting it finish it's current unit of work, * then doing any necessary cleanup and terminating * the thread. Notice that this does not guarentee * the thread will stop, as doUnitOfWork() could * block if not properly implemented. */ public void stop() { stopWork = true; } protected void done() { done = true; } protected void setup() { } protected void cleanup() { } /** * Does as small a unit of work as can be defined * for this thread. Once there is no more work to * be done, done() should be called. */ protected abstract void doUnitOfWork(); } 

你暗示你不是这些主题的作者,这表明他们可能无法安全地停止。 在这种情况下,你可以调用Thread.interrupt()来指示线程停止它正在做的事情(而不是上面描述的模式,你可以使用Thread.interrupt()来达到类似的效果)但是类似地,如果线程的设计者没有写它来处理中断,这可能不会做任何事情或导致不一致的状态或其他错误。

最终,如果您只想“[强制]线程停止执行”而无法修改线程的实现,那么Thread.stop()就是您想要的; 然而就像在Unix中使用kill一样,这是一个危险的命题,你应该基本上认为你的JVM在以这种方式终止线程后处于不稳定和不可修复的状态,并试图在此后尽快退出程序。


关于你打断中断然后停止的建议:

这里仍然存在很多问题,特别是中断并不能保证线程会立即中断(它的工作原理与上面的StoppableRunnable相似,但不太明确),而是设置了一个标志,线程应尽可能中断。 这意味着你可以调用Thread.interrupt() ,线程可以启动它正确的中断处理行为,然后在中途,你对Thread.stop()调用触发,猛烈地杀死线程并可能破坏你的JVM。 对Thread.interrupt()调用并不保证线程何时或如何响应该中断,这就是我更喜欢StoppableRunnable的显式行为的原因。 不用说,如果你打算调用Thread.stop() ,首先调用Thread.interrupt()几乎无法获得。 我不推荐它,但你也可以先调用Thread.stop()

另外,要认识到运行循环的代码本身就在一个线程中 – 这意味着你的循环可以很好地自杀,让所有其他线程都运行。

我用过这段代码:

 package com.xxx; import com.xxx.tools.messageLog; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author Mostafa Nazari */ public class ProcessAgent extends Thread{ public ProcessAgent() { super("Process-Agent"); } @Override public void run() { try { com.xxx.Process.agent.Main.main(new String[]{}); } catch (Exception ex) { if (ex instanceof InterruptedException) { messageLog.stdwar("Process Agent Stopped"); }else { messageLog.stderr("FATAL Error: "+ex.getMessage()); Logger.getLogger(ProcessAgent.class.getName()).log(Level.SEVERE, null, ex); } } } public void terminate() { if (super.isAlive()) { ThreadGroup group = super.getThreadGroup(); while (group != null) { group .interrupt(); group = super.getThreadGroup(); } super.interrupt(); } } public String getStatus() { if (super.isAlive()) { return "running"; } else { if (super.isInterrupted()) return "stopping"; else return "stopped"; } } } 

希望它对这个问题有用

而不是创建普通的Thread ,使用高级并发 API,如ExecutorService或ThreadPoolExecutor

您可以在这篇文章中查看不同的API:

Java的Fork / Join vs ExecutorService – 何时使用哪个?

有关强制关闭ExecutorService的问题,请参阅下面的SE问题:

如何强制关闭java ExecutorService