Wait until child threads completed : Java

You can do:

Thread t = new Thread() {
    public void run() {
        System.out.println("text");
        // other complex code
    }
 };
 t.start();
 t.join();

This way you will wait until the thread finishes and just then continue. You can join multiple threads:

for (Thread thread : threads) {
  thread.join();
}

In Java 8 a far better approach is to use parallelStream()

Note: it is far easier to see exactly what these background tasks are doing.

public static void main(String[] args) {
    Stream.<Runnable>of(
         () -> mytest.result.setIntValue(346635),
         () -> mytest.result.setStringValue("Hello hi"),
         () -> mytest.result.setBoolValue(true) )
         .parallel()
         .forEach(Runnable::run);

    System.out.println("main finished");
    System.out.println("Result is : " + mytest.result.toString());
}

I took out the debug information and the sleep as these don't alter the outcome.


You may want to choose CountDownLatch from java.util.concurrent. From JavaDocs:

A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.

Sample code:

import java.util.concurrent.CountDownLatch;

public class Test {
    private final ChildThread[] children;
    private final CountDownLatch latch;

    public Test() {
        this.children = new ChildThread[4];
        this.latch = new CountDownLatch(children.length);
        children[0] = new ChildThread(latch, "Task 1");
        children[1] = new ChildThread(latch, "Task 2");
        children[2] = new ChildThread(latch, "Task 3");
        children[3] = new ChildThread(latch, "Task 4");
    }

    public void run() {
        startChildThreads();
        waitForChildThreadsToComplete();
    }

    private void startChildThreads() {
        Thread[] threads = new Thread[children.length];

        for (int i = 0; i < threads.length; i++) {
            ChildThread child = children[i];
            threads[i] = new Thread(child);
            threads[i].start();
        }
    }

    private void waitForChildThreadsToComplete() {
        try {
            latch.await();
            System.out.println("All child threads have completed.");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private class ChildThread implements Runnable {
        private final String name;
        private final CountDownLatch latch;

        protected ChildThread(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                // Implementation
                System.out.println(name + " has completed.");
            } finally {
                latch.countDown();
            }
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.run();
    }
}

Output:

Task 1 has completed. Task 4 has completed. Task 3 has completed. Task 2 has completed. All child threads have completed.


I would recommend looking at the Executors framework first, and then look into the CompletionService.

Then you can write something like this:

ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse);
CompletionService completion = new ExecutorCompletionService(executor);
for (each sub task) {
    completion.submit(new SomeTaskYouCreate())
}
// wait for all tasks to complete.
for (int i = 0; i < numberOfSubTasks; ++i) {
     completion.take(); // will block until the next sub task has completed.
}
executor.shutdown();