我有一个多线程Java项目,我想添加一个方法停止()来停止所有正在运行的线程。 问题是,这个项目是由别人开发的东西,和我不熟悉它是如何实现多线程。
我所知道的是,一旦项目开始,许多线程调用,他们永远运行。 有没有办法找出所有正在运行的线程,并阻止他们? 我寻觅了很多,发现如何让正在运行的线程的列表:
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
旁边停止所有正在运行的线程怎么办?
为什么我要停止这些线程的原因是,我需要部署这个项目作为一个包OSGi容器。 一旦bundle启动,多线程运行下去。 所以,我需要实现一个destroy()方法来停止所有的线程控制包的生命周期。
怎么样
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();
}
这是一种危险的想法。 的Javadoc Thread.stop()
解释说:
这种方法本身具有不安全。 停止螺纹与使用Thread.stop使其解锁所有它已经锁定(作为未检查ThreadDeath异常堆栈向上传播的自然结果)的监视器。 如果以前受这些监视器保护的对象都处于一种不一致的状态,则损坏的对象将对其他线程可见,可能导致任意的行为。 停止的许多使用都应由只修改某些变量以指示目标线程应该停止运行的代码来代替。 目标线程应定期检查该变量,并从其运行方法以有序的方式返回,如果该变量指示它要停止运行。 如果目标线程等待很长时间(在一个条件变量,例如),中断方法应当用于中断的等待。
从根本上说,线程需要建立和设计可安全地终止,这是不可能安全地杀死任意线程。 相当标准的模式实现,像这样:
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()
到类似效果),但是同样,如果线程的设计不是招“T写它来处理中断,这可能不是做什么或导致不一致的状态或者其他错误。
最后, Thread.stop()
是你想要的,如果你只是想什么“[组]线程停止执行”,并不能修改该线程的执行情况; 但喜欢用kill
在Unix中,这是一个危险的命题,你应该基本考虑您的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的叉/加入VS ExecutorService的-什么时候使用?
请参阅下面SE问题进行强制关闭的ExecutorService下来:
如何强制关机的Java的ExecutorService