CountDownLatch vs Semaphore

Are there any benefits to using

java.util.concurrent.CountdownLatch

instead

java.util.concurrent.Semaphore ?

As far as I can tell, the following snippets 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 No. 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 the latch is created.)

So, in what situation might a latch be preferred?

+78
java multithreading concurrency semaphore countdownlatch
Oct 08 '08 at 18:25
source share
6 answers

CountDown capture is often used for the exact opposite of your example. Typically, you will have many threads blocking "wait ()", which will start at the same time when the counter reaches 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 can also use this as an β€œMPI-style" barrier, which keeps all threads waiting for other threads to reach a certain point before continuing.

 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(); } 

To do this, the CountDown latch can be safely used as shown in your example.

+91
Oct 08 '08 at 19:53
source share

CountDownLatch is used to start a series of threads, and then wait until they are all completed (or until they call countDown() given number of times.

A semaphore is used to control the number of parallel threads that use a resource. This resource can be something like a file or it can be a processor, limiting the number of threads that can be executed. The Semaphore count can go up and down, since different threads are called acquire() and release() .

In your example, you are essentially using Semaphore as a kind of CountUPLatch. Given that you intend to wait for all threads to complete, using CountdownLatch makes your intention more clear.

+57
Oct 08 '08 at
source share

Short description:

  • Semaphore and CountDownLatch serve for different purposes.

  • Use Semaphore to control access to resources.

  • Use CountDownLatch to wait for all threads to complete.

Semaphore definition from javadocs:

The semaphore supports a set of permissions. Each acquire () blocks, if necessary, until permission is obtained, and then takes it. Each release () adds permission, potentially freeing the blocking buyer.

However, no real permission objects are used; The semaphore simply counts the number of available and acts accordingly.

How it works?

Semaphores are used to control the number of parallel threads that use a resource. This resource can be something like general data or a block of code ( critical section ) or any file.

The Semaphore count can go up and down, since different threads are called acquire () and release (). But at any given time, you cannot increase the number of threads more than the number of Semaphores.

Semaphore Use cases:

  • Limiting concurrent disk access (this may cause a competing disk to be searched)
  • Topic Creation Restriction
  • JDBC Pool / Constrain
  • Network Connection Management
  • Throttling tasks with a processor or memory

Have a look at this article to use semaphore.

Definition of CountDownLatch from javadocs:

A synchronization helper that allows one or more threads to wait for a set of operations in other threads to complete.

How it works?

CountDownLatch works by having a counter initialized by the number of threads, which decreases every time a thread completes its execution. When the counter reaches zero, this means that all threads have completed execution, and waiting for the thread on the latch will resume execution.

CountDownLatch Use Cases:

  • Maximizing Parallelism: Sometimes we want to run multiple threads at the same time to achieve maximum parallelism
  • Wait for N threads to complete before starting.
  • Definition of a dead end.

Take a look at the article to clearly understand the concept of CountDownLatch.

Check out the Fork Join Pool in this article too. It has some similarities with CountDownLatch.

+9
Nov 10 '15 at 7:12
source share

Say you entered the golf store hoping to find a four,

When you queue to get time from one of the store sellers, you proshopVendorSemaphore.acquire() called proshopVendorSemaphore.acquire() , as soon as you get the tee time, you called proshopVendorSemaphore.release() . Note: any of the free operators can serve you, i.e. shared resource.

Now you come to the starter, it starts CountDownLatch(4) and calls await() to wait for others, for your part you called check-in, i.e. CountDownLatch . countDown() , as well as the rest of foursome. When everyone arrives, the starter gives ahead ( await() returns the call)

Now, after nine holes, when each of you takes a break, hypothetically allows you to use the starter again, he uses the β€œnew” CountDownLatch(4) to disable Hole 10, the same wait / sync as hole 1.

However, if the starter used a CyclicBarrier to start, it could have reset the same instance in Hole 10 instead of the second latch that they use and throw.

+3
Aug 01 '13 at 22:16
source share

Looking at a freely available source, in the implementation of the two classes there is no magic, so their performance should be the same. Choose the one that makes your intention more obvious.

+1
Oct 08 '08 at 19:31
source share

CountdownLatch causes threads to wait using the wait () method until the counter reaches zero. Therefore, perhaps you want all your threads to wait until 3 calls of something, then all threads can go. The latch cannot be reset at all.

The semaphore allows threads to obtain permissions, which prevents too many threads from executing at the same time, blocking if it cannot obtain the permission (s) that is required to continue. Permissions can be returned to Semaphore so that other pending threads continue.

0
Oct 08 '08 at 19:25
source share



All Articles