java - 如何在 java 中等待一组线程 'really' 完成?

标签 java multithreading

我在java中有一组线程,我想运行几次(每次使用一组不同的参数)。为了开始第二次运行,我想等待第一次运行完成。这应该可以在第二次运行之前使用 Thread.join() 轻松完成,但由于我的线程在无限循环中运行,我必须通过中断来停止它们,这也会中断阻塞连接:

我有一个线程,其 run() 方法基本上如下所示:

try {  
    while(true) {  
        printSomeInfo();
        if (...) {
            Thread.currentThread().getThreadGroup().interrupt();
        }
    } 
} catch (InterruptedException e) {  
    Thread.currentThread().getThreadGroup().interrupt();  
} finally {  
    printStats();
}

还有一个调用线程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 block 中的 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

我怎样才能真正等待第一组线程完成?是否有一种更有选择性的方法来中断正在运行的线程?

最佳答案

问题在于您重复使用Thread.currentThread().getThreadGroup().interrupt()它会中断 ThreadGroup 中的所有线程,包括名为 join 的那个.

如果你看看你的循环,你就会发现 InterruptedException ,但无法正确恢复。您的循环包含在 try…catch 中 block 并因此被异常强制终止。既然你要调用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
    }
}

通常,中断整个 ThreadGroup ,或者根本处理过时的线程组概念,都不是正确的软件设计。您应该重写您的软件以仅中断预期的线程。或者简单地使用并发框架,尤其是。 ExecutorService它已经提供了提交任务组并取消或等待所有任务的方法。

关于java - 如何在 java 中等待一组线程 'really' 完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27245731/

相关文章:

c# - readerwriterlock 允许在获取写锁时读取?

c# - 多线程检查

c - OMP 2.0 嵌套 For 循环

java - 如何用 Java 验证加拿大邮政编码?检查两种类型的输入?前 : accepting A1A1A1 and A1A 1A1

java - URLConnection 连接的 getter

java - 查找对象在哪个类中实例化

java - Java 中的多线程排序动画

java - 如何禁用 Intellij IDEA 功能,该功能不允许我在 pom.xml 中输入结束字符 ">"?

java - DataOutputStream 不同的方法

java - java如何区分Lambda中的Callable和Runnable?