How to get java.concurrency.CyclicBarrier to work as expected

I am writing code that will spawn two threads and then wait for them to synchronize using the CyclicBarrier class. The problem is that the cyclic barrier does not work as expected, and the main thread does not wait for the completion of individual threads. This is what my code looks like:

class mythread extends Thread{ CyclicBarrier barrier; public mythread(CyclicBarrier barrier) { this.barrier = barrier; } public void run(){ barrier.await(); } } class MainClass{ public void spawnAndWait(){ CyclicBarrier barrier = new CyclicBarrier(2); mythread thread1 = new mythread(barrier).start(); mythread thread2 = new mythread(barrier).start(); System.out.println("Should wait till both threads finish executing before printing this"); } } 

Any idea what I'm doing wrong? Or is there a better way to write these barrier synchronization methods? Please help.

+7
java multithreading concurrency cyclicbarrier
source share
4 answers

During the execution of the main thread, you create two other threads and tell them to wait for each other. But you did not write anything so that your main thread waits for them and complains that it is not waiting. Try

 CyclicBarrier barrier = new CyclicBarrier(3); mythread thread1 = new mythread(barrier).start(); mythread thread2 = new mythread(barrier).start(); barrier.await(); // now you wait for two new threads to reach the barrier. System.out.println("Should wait till both threads finish executing before printing this"); 

BTW. Do not extend the Thread class if necessary. Deploy Runnable and pass implementations to Thread objects. Like this:

 class MyRunnable implements Runnable { public void run(){ // code to be done in thread } } Thread thread1 = new Thread(MyRunnable); thread1.start(); 

EDIT
The rationale for preventing the spread of Thread.
A rule of thumb is combined as little as possible. Inheritance is a very strong link between classes. You must inherit from Thread if you want to change some of your default actions (for example, override some methods) or want to access some protected fields of the Thread class. If you do not want this, you select looser connection - implement Runnable and pass it as a constructor parameter to the Thread instance.

+14
source share

Pass the Runnable instance to the constructor of your CyclicBarrier like this.

 CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() { @Override public void run() { System.out.println("Should wait till both threads finish executing before printing this"); } }); new mythread(barrier).start(); new mythread(barrier).start(); 
+2
source share

You are looking for Thread.join () method ...

 thread1.join(); thread2.join(); System.out.println("Finished"); 

EDIT: due to comments ...

And if you do not want to wait forever, you can also specify the maximum number of milliseconds plus nanoseconds to wait until the thread dies.

+2
source share

The cyclic barrier is not the right choice in this case. Here you should use CountDownLatch .

I assume that you are calling the spawnAndWait method from the main method.

The reason this doesn't work is because CyclicBarrier has 2 constructors. To perform post-operations, you must use the parameter constructor 2. The most important thing to remember is that the main thread will not wait with await ; but will continue to be executed. However, the stream specified in the constructor of the CyclicBarrier starts only when all the generated threads stop at the barrier (using the await method)

+1
source share

All Articles