Как ждать завершения ряда потоков? - PullRequest
98 голосов
/ 10 августа 2009

Как можно просто дождаться завершения всех потоковых процессов? Например, скажем, у меня есть:

public class DoSomethingInAThread implements Runnable{

    public static void main(String[] args) {
        for (int n=0; n<1000; n++) {
            Thread t = new Thread(new DoSomethingInAThread());
            t.start();
        }
        // wait for all threads' run() methods to complete before continuing
    }

    public void run() {
        // do something here
    }


}

Как мне изменить это, чтобы метод main() приостанавливал комментарий, пока не завершатся методы всех потоков run()? Спасибо!

Ответы [ 13 ]

1 голос
/ 17 сентября 2014

Создайте объект потока внутри первого цикла for.

for (int i = 0; i < threads.length; i++) {
     threads[i] = new Thread(new Runnable() {
         public void run() {
             // some code to run in parallel
         }
     });
     threads[i].start();
 }

И так, что все здесь говорят.

for(i = 0; i < threads.length; i++)
  threads[i].join();
0 голосов
/ 16 сентября 2016

В качестве альтернативы CountDownLatch вы также можете использовать CyclicBarrier например,

public class ThreadWaitEx {
    static CyclicBarrier barrier = new CyclicBarrier(100, new Runnable(){
        public void run(){
            System.out.println("clean up job after all tasks are done.");
        }
    });
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            Thread t = new Thread(new MyCallable(barrier));
            t.start();
        }       
    }

}    

class MyCallable implements Runnable{
    private CyclicBarrier b = null;
    public MyCallable(CyclicBarrier b){
        this.b = b;
    }
    @Override
    public void run(){
        try {
            //do something
            System.out.println(Thread.currentThread().getName()+" is waiting for barrier after completing his job.");
            b.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }       
}

Для использования CyclicBarrier в этом случае барьер .await () должен быть последним оператором, т. Е. Когда ваш поток завершает свою работу. CyclicBarrier может быть снова использован с его методом reset (). Чтобы процитировать Javadocs:

CyclicBarrier поддерживает необязательную команду Runnable, которая запускается один раз для каждой точки барьера, после прибытия последнего потока в партии, но до того, как какие-либо потоки будут освобождены. Это барьерное действие полезно для обновления общего состояния до того, как какая-либо из сторон продолжит.

0 голосов
/ 10 августа 2009

Вы можете сделать это с Объектом "ThreadGroup" и его параметром activeCount :

...