如何暂停main()直到所有其他线程都死掉?

在我的程序中,我在main()方法中创建了几个线程。 main方法的最后一行是对System.out.println()的调用,在所有线程都已经死亡之前我不想调用它。 我已经尝试在每个线程上调用Thread.join()但是阻塞每个线程以便它们顺序执行而不是并行执行。

有没有办法阻止main()线程,直到所有其他线程完成执行? 这是我的代码的相关部分:

public static void main(String[] args) { //some other initialization code //Make array of Thread objects Thread[] racecars = new Thread[numberOfRaceCars]; //Fill array with RaceCar objects for(int i=0; i<numberOfRaceCars; i++) { racecars[i] = new RaceCar(laps, args[i]); } //Call start() on each Thread for(int i=0; i<numberOfRaceCars; i++) { racecars[i].start(); try { racecars[i].join(); //This is where I tried to using join() //It just blocks all other threads until the current //thread finishes. } catch(InterruptedException e) { e.printStackTrace(); } } //This is the line I want to execute after all other Threads have finished System.out.println("It's Over!"); } 

谢谢你的帮助!

埃里克

您启动线程并立即等待它们完成(使用join() )。 相反,你应该在另一个for循环中的for循环之外执行join() ,例如:

 // start all threads for(int i=0; i 

您可以在RaceCar和主线程之间共享一个CyclicBarrier对象,并让RaceCar线程在完成任务后立即调用await() 。 使用RaceCar线程数加一(用于主线程)构造屏障。 所有RaceCar完成后,主线程将继续。 请参阅http://java.sun.com/javase/6/docs/api/java/util/concurrent/CyclicBarrier.html

详细地说,在主线程中构造一个CyclicBarrier ,并在run()方法退出之前在RaceCar类中添加一个barrier.await()调用,同时在System.out.println()之前添加一个barrier.await()调用System.out.println()在你的主线程中调用。

您可以在主线程中wait()并让所有线程在完成后发出notifyAll() 。 然后每当你的主线程以这种方式唤醒时,它可以检查是否至少有一个线程仍处于活动状态,在这种情况下你会wait()更多。

您可以使用join方法。 请参阅此处的文档

您可以为“其结束”消息添加关闭挂钩。 这样,它将在程序完成时生成,您不必等待每个线程。

您可以将最后一行放在“监视”线程中。 它会经常检查它是唯一正在运行的线程,并且某些完成状态== true然后可能会触发它。 然后它可以做除了println之外的其他事情

最简单的方法

 while (Thread.activeCount() > 1) { } 

我知道它阻止主线程……但它完美无缺!

试试这个例子:

 public class JoinTest extends Thread { public static void main(String[] args) { JoinTest t = new JoinTest(); t.start(); try { t.join(); int i = 0; while(i<5) { System.out.println("parent thread is running......" +i++); } } catch (Exception e) { // TODO: handle exception } } public void run() { try { int i =0; while(i<5) { System.out.println("child thread running ........." +i++); } } catch (Exception e) { // TODO: handle exception } } } 

如果你去ExecutorService或ThreadPoolExecutor框架,你有更好的选择。

  1. 的invokeAll

    执行给定的任务,返回完成所有状态和结果的Futures列表。 Future.isDone()对于返回列表的每个元素都为true。 请注意,已完成的任务可能正常终止或通过抛出exception终止。 如果在此操作正在进行时修改了给定集合,则此方法的结果未定义。 类型参数:

  2. CountDownLatch :使用计数器初始化CountDownLatch作为线程数。 使用countDown()await() API并等待计数器变为零。

进一步参考:

如何使用invokeAll()让所有线程池完成他们的任务?

CountDownLatch如何在Javamultithreading中使用?