我正在编写一个程序,我从main函数调用多个线程。有一个For循环,它在循环中启动线程。 我想实现一个功能,如果在一个线程中发生某些异常,那么它应该停止所有当前正在运行/提交的线程,或者处于等待状态的线程。此外,不应再从循环中提交更多的线程。
P.S。我正在维护一个Map,它记录所有线程Map <threadName, Thread>
而且我没有使用执行服务。
如何杀死或停止所有线程,并防止在任何一个线程发生异常后提交更多线程。
答案 0 :(得分:2)
请注意,没有“内置”功能可以在java中停止某个线程 - 某些方法确实存在,但所有方法都已弃用,因为如果正在运行的代码不合作,它们可能会造成麻烦。所以你的代码必须实现一些方法来基于某个标志退出run()
- 方法,这必须在线程外部设置。如果你的帖子正在使用wait()
,那么拨打interrupt()
可能会派上用场。
答案 1 :(得分:2)
您无法在Java中强制停止线程。
是的,有Thread.stop()
和相关的方法,但它们已被弃用多年for good reason。
为什么
Thread.stop
已被弃用?
因为它本质上是不安全的。停止线程会导致它解锁已锁定的所有监视器。 (当ThreadDeath
异常向上传播时,监视器将被解锁。)如果先前受这些监视器保护的任何对象处于不一致状态,则其他线程现在可以以不一致的状态查看这些对象。据说这些物体已被损坏。当线程对受损对象进行操作时,可能会导致任意行为。这种行为可能很微妙并且难以检测,或者可能是明显的。与其他未经检查的异常不同,ThreadDeath
会默默地杀死线程;因此,用户没有警告他的程序可能被破坏。腐败可以在实际损害发生后的任何时间显现,甚至在未来几小时或几天。
由于上述原因,您不应该使用这些方法,也不要依赖它们(许多使用线程繁重方法的API会很乐意忽略对stop()
和interrupt()
的任何调用)。
一旦我们解决了这个问题,你仍然可以为你的线程实现逻辑,以便在你提出要求时尽快终止。
你需要做两件事:
1.-检查Thread.interrupted()
方法中的run()
。像这样:
@Override
public synchronized void run() {
while (yourFinishCondition && !Thread.interrupted()) {
// do stuff until you finish, or until the thread is interrupted from the outside
}
}
2.-在主要方法的每个线程上调用interrupt()
,以便在需要时发出终止信号,如下所示:
Thread.UncaughtExceptionHandler h = (thread, exception) -> {
thread0.interrupt();
thread1.interrupt();
thread2.interrupt();
};
一点点PoC:
public class Main {
static class MyThread extends Thread {
public MyThread(String s) {
super(s);
}
@Override
public synchronized void run() {
while(!Thread.interrupted()) {
if (new Random().nextInt(1000000) == 7) {
throw new RuntimeException(Thread.currentThread().getName()+" oops!");
}
}
System.out.println(Thread.currentThread().getName()+" interrupted");
}
}
public static void main(String[] args) {
final MyThread thread0 = new MyThread("thread0");
final MyThread thread1 = new MyThread("thread1");
final MyThread thread2 = new MyThread("thread2");
Thread.UncaughtExceptionHandler h = (thread, exception) -> {
System.out.println(exception.getMessage());
thread0.interrupt();
thread1.interrupt();
thread2.interrupt();
};
thread0.setUncaughtExceptionHandler(h);
thread1.setUncaughtExceptionHandler(h);
thread2.setUncaughtExceptionHandler(h);
thread0.start();
thread1.start();
thread2.start();
}
}
输出:
thread2 oops!
thread1 interrupted
thread0 interrupted
答案 2 :(得分:0)
您可以编写代码来终止finally块或catch块中的所有正在运行的线程(可能不推荐使用)
在杀死所有正在运行的线程时,refer this thread
答案 3 :(得分:-1)
如果我问你的问题是正确的,你需要捕获异常并需要保持/维护列表作为共享对象,然后在其他线程上调用thread.stop()
会解决问题吗?但是在最近的java版本中不推荐stop
方法,所以你可以使用thread.yield()
使线程释放CPU和其他资源,但它仍然不能保证线程的立即终止。