Li'*_*Li' 16 java multithreading osgi
我有一个多线程java项目,我想添加一个方法stop()来停止所有正在运行的线程.问题是这个项目是由其他人开发的,我不熟悉它如何实现多个线程.
我所知道的是,一旦项目开始,就会调用许多线程并且它们会永远运行.有没有办法找到所有正在运行的线程并阻止它们?我搜索了很多,并找到了如何获取正在运行的线程列表:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
Run Code Online (Sandbox Code Playgroud)
下一步要做什么来阻止所有正在运行的线程?
我想要停止这些线程的原因是我需要将此项目作为一个包部署到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();
}
Run Code Online (Sandbox Code Playgroud)
dim*_*414 21
这是一个危险的想法.Javadoc Thread.stop()解释说:
这种方法本质上是不安全的.使用Thread.stop停止一个线程会导致它解锁它已锁定的所有监视器(这是未经检查的ThreadDeath异常向上传播的自然结果).如果先前受这些监视器保护的任何对象处于不一致状态,则受损对象对其他线程可见,可能导致任意行为.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();
}
Run Code Online (Sandbox Code Playgroud)
你暗示你不是这些主题的作者,这表明他们可能无法安全地停止.在这种情况下,你可以调用Thread.interrupt()指示线程停止它正在做的事情(而不是上面描述的模式,你可以使用Thread.interrupt()类似的效果)但是类似地,如果线程的设计者没有写它来处理中断,这可能不做任何事情或造成不一致的状态或其他错误.
最终,Thread.stop()如果你只想"[强制]线程停止执行"而不能修改线程的实现,那么你想要的是什么; 然而,就像kill在Unix中使用一样,这是一个危险的命题,你应该基本上认为你的JVM在以这种方式终止线程后处于不稳定和不可修复的状态,并试图在此后尽快退出程序.
关于你打断中断然后停止的建议:
这里仍然存在很多问题,特别是中断并不能保证线程会立即中断(它的工作方式类似,虽然不太明确,但是我的StoppableRunnable上面的内容),而是设置了一个标志,线程应尽可能中断.这意味着你可以调用Thread.interrupt(),线程可以启动它正确的中断处理行为,然后在中途,你的Thread.stop()激活,猛烈杀死线程并可能破坏你的JVM.调用Thread.interrupt()不保证线程何时或如何响应该中断,这就是我更喜欢显式行为的原因StoppableRunnable.毋庸置疑,如果你打算打电话,那么首先打电话Thread.stop()几乎没有什么好处Thread.interrupt().我不推荐它,但你也可以Thread.stop()在第一时间打电话.
另外,要认识到运行循环的代码本身就在一个线程中 - 这意味着你的循环可以很好地自杀,让所有其他线程继续运行.