Main thread to wait two parallel threads children java

1k Views Asked by At

first what i am trying to do:

During the main thread execution i want to pause the main thread and start two parallel threads. As soon as both this parallel threads terminate, i'd like to start again with the main thread.

What i tried:

    ...
    ...
    main thread is executing
    ...
    ...
CyclicBarrier barrier = new CyclicBarrier(2);
Thread child1 = new Thread(new ThreadBuilderTask(barrier,0));
Thread child2 = new Thread(new ThreadBuilderTask(barrier,1));

child1.start();
child2.start(); 

/* Now i'm expecting that child1 and child2 are running in parallel calling their fooFunction */

child1.join();
child2.join(); 
/*Now i'm expecting that main thread will wait for child1and also for child2 (that are running in parallel).*/

... main thread starts again after both child1 and child2 finished (reached the await of the barrier) 
... (break point set here, never reached)
...

Thread builder custom class

public class ThreadBuilderTask implements Runnable{
    private CyclicBarrier barrier;
    private int index;
    ...setters and getters..

    @Override
    public void run() {
        fooFunction(this.getIndex());
        try {
            this.getBarrier().await();
        } catch (InterruptedException | BrokenBarrierException e) {
            return;
        }
    }

    public ThreadBuilderTask(CyclicBarrier barrier,int index){
      this.barrier = barrier;
      this.index = index;
    }

    public fooFunction(int index){
        //Something taking some seconds to execute
    }

It's not clear what is happening here but it is definetely not working. As soon as i call join everything stops and the main thread never restart. (I put a breakpoint after the joins to see when the main thread restarts).

Maybe there is a bit of confusion with these concepts and also i'm not sure if i need to use both the barrier and the joins or simply one of those techniques.

Thanks

Davide

2

There are 2 best solutions below

2
On BEST ANSWER

As mentioned in the comments I'd also suggest to use CompletableFuture. A very basic example of your described requirements could look like this:

final Runnable runnable1 = ...;
final Runnable runnable2 = ...;

CompletableFuture<Void> future1 = CompletableFuture.runAsync(runnable1);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(runnable2);

CompletableFuture.allOf(future1, future2).get(); // waits for both runnables to finish

You might want to add more/some exception handling to this example. But it should give an idea how this might work.

0
On

You may consider to use Java CompletableFuture to achieve the objective.

Using its functions like supplyAsync or runAsync you may start child threads and join their respective result in the end. Or you can simply let the main thread wait until the subsequent threads completes.

Recently I managed to implement a sample scatter-gather function using the same class.

Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html