等待多个线程在Java中完成

A J*_*son 35 java multithreading synchronization

在程序执行过程中,会启动许多线程.线程数量取决于用户定义的设置,但它们都使用不同的变量执行相同的方法.

在某些情况下,执行中需要清理,其中一部分是停止所有线程,我不希望它们立即停止,我只是设置一个他们检查的变量来终止它们.问题是它可以在线程停止前最多1/2秒.但是,我需要确保在清理可以继续之前所有线程都已停止.清理是从另一个线程执行的,所以从技术上讲,我需要这个线程来等待其他线程完成.

我想到了几种方法,但它们似乎都过于复杂.我希望有一些方法可以等待一组线程完成.有这样的事吗?

谢谢.

Jon*_*eet 59

只需逐个加入:

for (Thread thread : threads) {
  thread.join();
}
Run Code Online (Sandbox Code Playgroud)

(你需要做一些事情InterruptedException,你可能希望在出现问题时提供暂停时间,但这是基本想法...)

  • @Jon Skeet,我有一个疑问.line`thread.join();`会使当前进程等到线程`thread`正在运行,对吧?那么这里会发生什么,主进程将进入第二行并将等待`thread`完成其工作,然后它将进入循环中的下一个'thread`,所以实际main将等到第一个子线程运行,那么它会为下一个线程执行`thread.join()`,对不对? (12认同)
  • 另一点需要注意的是,当主线程移动到第二个线程时,它可能已经完成了.在这种情况下,加入将立即返回.因此,主线程将继续加入第三个线程. (8认同)
  • @Jon skeet,请让我明白,我明白如果一个主线程调用thread.join(),那么主线程将被暂停,并且当线程`thread`完成时main将恢复.我做对了吗?现在,说变量`threads`中有3个线程,所以`for`循环将执行3次,第1次`thread` main将执行`.join()`然后它将被系统暂停并将被恢复当第一个线程完成时.然后只有它可以再循环下一个(第二)线程元素.我做对了吗? (4认同)

Tad*_*pec 14

如果您使用的是Java 1.5或更高版本,则可以尝试使用CyclicBarrier.您可以将清理操作作为其构造函数参数传递,并barrier.await()在需要清理时调用所有线程.

  • 另一种方法是,如果你只这样做一次,就是使用CountdownLatch. (3认同)

Ken*_*ter 9

你看过Executor课了java.util.concurrent吗?你可以运行你的线程ExecutorService.它为您提供了一个可用于取消线程或等待它们完成的对象.


oxb*_*kes 8

自己定义一种实用方法(或多种方法):

public static waitFor(Collection<? extends Thread) c) throws InterruptedException {
    for(Thread t : c) t.join();
}
Run Code Online (Sandbox Code Playgroud)

或者你可能有一个阵列

public static waitFor(Thread[] ts) throws InterruptedException {
    waitFor(Arrays.asList(ts));
}
Run Code Online (Sandbox Code Playgroud)

另外,您可以看看使用CyclicBarrierjava.util.concurrent库来实现任意交会多个线程之间的点.