如何等待一组线程';真的';用java完成吗?
我有一组java线程,我想运行几次(每次都使用不同的参数集)。要开始第二次跑步,我要等待第一次跑步结束。这应该在第二次运行之前通过如何等待一组线程';真的';用java完成吗?,java,multithreading,Java,Multithreading,我有一组java线程,我想运行几次(每次都使用不同的参数集)。要开始第二次跑步,我要等待第一次跑步结束。这应该在第二次运行之前通过Thread.join()轻松完成,但由于我的线程在无限循环中运行,我必须通过中断来停止它们,这也会中断阻塞连接: 我有一个线程,其run()方法基本上如下所示: try { while(true) { printSomeInfo(); if (...) { Thread.currentThrea
Thread.join()
轻松完成,但由于我的线程在无限循环中运行,我必须通过中断来停止它们,这也会中断阻塞连接:
我有一个线程,其run()
方法基本上如下所示:
try {
while(true) {
printSomeInfo();
if (...) {
Thread.currentThread().getThreadGroup().interrupt();
}
}
} catch (InterruptedException e) {
Thread.currentThread().getThreadGroup().interrupt();
} finally {
printStats();
}
New run:
Info 1
Info 1
...
Info 1
New run:
(here comes the stack trace)
Info 2
Info 2
Stats 1 <- this should happen before the second "New run:"
...
Info 2
Stats 2
以及调用线程的run方法的main方法:
System.out.println("New run:");
for (i ...) { //first run
myThread[i] = new MyThread(someInfoString1);
myThread[i].start();
}
try {
for (i...) {
myThread[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("New run:");
for (i ...) { //second run
myThread[i] = new MyThread(someInfoString2);
myThread[i].start();
}
try {
for (i...) {
myThread[i].join();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
我的问题是,第二次运行开始打印信息,而第一次运行没有使用finally块中的printStats()方法完成打印。
因此,输出如下所示:
try {
while(true) {
printSomeInfo();
if (...) {
Thread.currentThread().getThreadGroup().interrupt();
}
}
} catch (InterruptedException e) {
Thread.currentThread().getThreadGroup().interrupt();
} finally {
printStats();
}
New run:
Info 1
Info 1
...
Info 1
New run:
(here comes the stack trace)
Info 2
Info 2
Stats 1 <- this should happen before the second "New run:"
...
Info 2
Stats 2
新运行:
信息1
信息1
...
信息1
新运行:
(这里是堆栈跟踪)
信息2
信息2
Stats 1问题在于重复使用Thread.currentThread().getThreadGroup().interrupt()
,它会中断ThreadGroup
中的所有线程,包括调用join
的线程
如果查看循环,您正在捕获中断异常
,但没有正确恢复。循环包含在try…catch
块中,因此被异常强制终止。由于要在所有线程上调用join
,因此必须继续循环,包括已中断的join
调用:
threads: for (i...) { // loop over all threads
for(;;) { // recover join on InterruptedException
try {
myThread[i].join();
continue threads; // after successful join
} catch (InterruptedException e) {} // call join again
}
}
通常,中断整个线程组
,或者处理过时的线程组概念,都不是一种正确的软件设计。你应该重写你的软件,只中断插入的线程。或者简单地使用并发框架,特别是ExecutorService
,它已经提供了提交任务组和取消或等待所有任务的方法。如果一段代码必须在另一段之后运行,为什么不使用一个线程呢?因为有些部分应该并行完成?OP正在使用一个线程来编排其他线程。