Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CountDownLatch vs. Semaphore

Is there any advantage of using

java.util.concurrent.CountdownLatch

instead of

java.util.concurrent.Semaphore?

As far as I can tell the following fragments are almost equivalent:

1. Semaphore

final Semaphore sem = new Semaphore(0); for (int i = 0; i < num_threads; ++ i) {   Thread t = new Thread() {     public void run()     {       try       {         doStuff();       }       finally       {         sem.release();       }     }   };   t.start(); }  sem.acquire(num_threads); 

2: CountDownLatch

final CountDownLatch latch = new CountDownLatch(num_threads); for (int i = 0; i < num_threads; ++ i) {   Thread t = new Thread() {     public void run()     {       try       {         doStuff();       }       finally       {         latch.countDown();       }     }   };   t.start(); }  latch.await(); 

Except that in case #2 the latch cannot be reused and more importantly you need to know in advance how many threads will be created (or wait until they are all started before creating the latch.)

So in what situation might the latch be preferable?

like image 548
finnw Avatar asked Oct 08 '08 18:10

finnw


1 Answers

CountDownLatch is frequently used for the exact opposite of your example. Generally, you would have many threads blocking on await() that would all start simultaneously when the countown reached zero.

final CountDownLatch countdown = new CountDownLatch(1);  for (int i = 0; i < 10; ++ i) {    Thread racecar = new Thread() {           public void run() {          countdown.await(); //all threads waiting          System.out.println("Vroom!");       }    };    racecar.start(); } System.out.println("Go"); countdown.countDown();   //all threads start now! 

You could also use this as an MPI-style "barrier" that causes all threads to wait for other threads to catch up to a certain point before proceeding.

final CountDownLatch countdown = new CountDownLatch(num_thread);  for (int i = 0; i < num_thread; ++ i) {    Thread t= new Thread() {           public void run() {          doSomething();          countdown.countDown();          System.out.printf("Waiting on %d other threads.",countdown.getCount());          countdown.await();     //waits until everyone reaches this point          finish();       }    };    t.start(); } 

That all said, the CountDownLatch can safely be used in the manner you've shown in your example.

like image 50
James Schek Avatar answered Oct 05 '22 23:10

James Schek