问题描述
我有一个多线程java项目,我想添加一个方法stop()来停止所有正在运行的线程。问题是这个项目是由其他人开发的,我不熟悉它如何实现多个线程。
我所知道的是,一旦项目开始,就会调用许多线程并且它们会永远运行。有没有办法找到所有正在运行的线程并阻止它们?我搜索了很多,并找到了如何获取正在运行的线程列表:
Set< Thread> 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();
}
这是一个危险的想法。用于解释:
从根本上说,线程需要构建和设计才能安全终止,不可能安全地杀死任意线程。一个相当标准的模式实现如下:
公共抽象类StoppableRunnable实现Runnable {
private volatile boolean stopWork ;;
private boolean done;
public final void run(){
setup();
while(!stopWork&&!done){
doUnitOfWork();
}
cleanup();
}
/ **
*安全地指示此线程停止工作,
*让它完成当前的工作单元,
*然后做任何必要的清理并终止
*线程。请注意,这不保证
*线程将停止,因为如果没有正确实现,doUnitOfWork()可以
*阻止。
* /
public void stop(){
stopWork = true;
}
protected void done(){
done = true;
}
protected void setup(){}
protected void cleanup(){}
/ **
*尽量小可以为此线程定义
*的工作单元。一旦完成
*的工作,就应该调用done()。
* /
protected abstract void doUnitOfWork();
}
您暗示您不是这些主题的作者,这表明他们可能不能安全地停止。在这种情况下,您可以致电指示线程停止它正在做的事情(而不是上面描述的模式,你可以使用 Thread.interrupt ()
到类似的效果)但是类似地,如果线程的设计者没有写它来处理中断,这可能不会做任何事情或导致不一致的状态或其他错误。
最终, Thread.stop()
就是你想要的[强制]线程停止执行而不能修改线程的实现;然而就像在Unix中使用 kill
一样,这是一个危险的命题,你应该基本上认为你的JVM在以这种方式终止线程后处于不稳定和不可修复的状态,并且尝试在此后尽快退出该计划。
关于您打断中断然后停止的建议:
这里仍然存在很多问题,特别是中断并不能保证线程会立即中断(它的工作方式与我的<$相似,但不太明确) c $ c> StoppableRunnable 以上)而是设置一个标志,线程应尽可能中断。这意味着你可以调用 Thread.interrupt()
,线程可以启动它正确的中断处理行为,然后在中途,你的线程调用.stop()
触发,猛烈杀死线程并可能破坏你的JVM。调用 Thread.interrupt()
不保证线程何时或如何响应该中断,这就是为什么我更喜欢 StoppableRunnable 。毋庸置疑,如果你打算调用 Thread.stop()
,那么通过调用 Thread.interrupt()来获得很少的东西
首先。我不推荐它,但你也可以先调用 Thread.stop()
。
本身在一个线程中 - 这意味着你的循环可以先杀死自己,让所有其他线程继续运行。
I have an multiple-threaded java project and I want to add a method stop() to stop all the running threads. The problem is that this project is developed by someone else, and I am not familiar with how it implements multiple threads.
What I know is that once the project get started, many threads are invoked and they run forever. Is there a way to find all running threads and stop them? I have searched a lot, and found how to get a list of running threads:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
What to do next to stop all the running threads?
The reason why I want to stop these threads is that I need to deploy this project to OSGi container as a bundle. Once the bundle is started, multiple threads run forever. So I need to implement a destroy() method to stop all threads to control the bundle lifecycle.
How about
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();
}
This is a dangerous idea. The Javadoc for Thread.stop()
explains:
Fundamentally, threads need to be built and designed to safely terminate, it is not possible to safely kill arbitrary threads. A fairly standard pattern is implemented like so:
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();
}
You implied you aren't the author of these threads, which suggest they may not be safely stoppable. In such a case, you can call Thread.interrupt()
to instruct the thread to stop what it's doing (instead of the pattern described above, you could use Thread.interrupt()
to similar effect) however similarly, if the thread's designer hasn't written it to handle interrupts, this may not do anything or cause inconsistent states or other errors.
Ultimately, Thread.stop()
is what you want if you just want to "[Force] the thread to stop executing" and can't modify the thread's implementation; however like using kill
in Unix, this is a dangerous proposition, and you should essentially consider your JVM to be in an unstable and irreparable state after terminating a thread in this way, and attempt to exit the program as quickly as possible thereafter.
Regarding your suggestion of interrupting then stopping:
There's still a lot of problems here, in particular, interrupting does not guarantee the thread will interrupt immediately (it works similarly, though less explicitly, to my StoppableRunnable
above) and instead sets a flag that the thread should interrupt when possible. This means you could call Thread.interrupt()
, the thread could start it's proper interrupt-handling behavior, then midway through that, your call to Thread.stop()
fires, violently killing the thread and potentially breaking your JVM. Calls to Thread.interrupt()
provide no guarantee as to when or how the thread will respond to that interrupt, which is why I prefer the explicit behavior in StoppableRunnable
. Needless to say, if you're ever going to call Thread.stop()
there's little to be gained by calling Thread.interrupt()
first. I don't recommend it, but you might as well just call Thread.stop()
in the first place.
Additionally, recognize that the code running your loop is itself in a thread - meaning your loop could very well kill itself first, leaving all other threads running.
这篇关于如何查找和停止所有当前运行的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!