Search code examples
javamultithreadingconcurrencyjava-threadscyclicbarrier

Main thread to wait two parallel threads children java


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


Solution

  • 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.