- A CountDownLatch allows one or more threads to wait until a set of operations being performed in other threads completes.
- A CountDownLatch is initialized with a given count.
- The await methods block until the current count reaches zero due to invocations of the countDown() method.
1. Scenario: Synchronize resources using CountDownLatch (concurrency)
- Friends has planned trip for their vacation.
- They have decided to meet at certain point before they can start for their vacation.
- We will use CountDownLatch for this purpose.
- Initialize CountDownLatch with number of friends planned for vacation.
- Decrement count down when new friend arrive to board for cab using CountDownLatch.countDown
- When count of CountDownLatch reaches zero, they will start for their vacation.
2. Program: Synchronize resources using CountDownLatch (example)
2.1 Passenger class:
- Passenger class implements Runnable interface.
- Passenger object calls shareCab.board method which would eventually decrements the count of CountDownLatch.
- Once count of CountDownLatch reaches zero, shareCab will resume its operation.
package org.learn;
public class Passenger implements Runnable {
private ShareCab shareCab;
private String passengerName;
public Passenger(ShareCab shareCab, String passengerName) {
this.shareCab = shareCab;
this.passengerName = passengerName;
}
@Override
public void run() {
int arrivalTime = (int) (Math.random() * 2000);
try {
Thread.sleep(arrivalTime);
shareCab.board(passengerName);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.2 ShareCab class:
- ShareCab class will wait for all passengers (friends) to get boarded.
- All threads participating in synchronization operation would wait using countDownLatch.await() method.
- ShareCab would wait for passengers using CountDownLatch.await method.
- When each passenger gets boarded, then each passenger will call CountDownLatch.countDown method (CountDownLatch reaches zero), then run method will resume its operation.
package org.learn;
import java.util.concurrent.CountDownLatch;
public class ShareCab implements Runnable {
private CountDownLatch countDownLatch;
public ShareCab(int nPassengers) {
countDownLatch = new CountDownLatch(nPassengers);
}
public void board(String passengerName) {
System.out.printf("\n%s has boarded the cab",passengerName);
countDownLatch.countDown();
}
@Override
public void run() {
System.out.printf("\nNumber of friends planned for trip: %d",
countDownLatch.getCount());
try {
//waiting for all threads.
countDownLatch.await();
System.out.printf("\nAll friends has boarded the cab. Let's start the journey");
} catch (InterruptedException e) {
System.out.println("Interruption exception has occurred");
}
}
}
2.3 DemoCountDownLatch class:
- DemoCountDownLatch class demonstrate the working of CountDownLatch.
- We will plan a trip for 7 friends using CountDownLatch.
- Create Passenger objects who are going for trip.
- ShareCab will wait for all passengers (friends) to get boarded the cab then we will plan our trip.
package org.learn;
public class DemoCountDownLatch {
private static int numberOfPassenger = 7;
public static void main(String[] args) {
//Book a cab - 7 Seater
ShareCab tripCab = new ShareCab(numberOfPassenger);
Thread cabThread = new Thread(tripCab);
cabThread.start();
//create passenger
for(int nPass = 1 ; nPass <= numberOfPassenger; nPass++) {
Passenger passenger = new Passenger(tripCab,"Passenger "+nPass);
Thread passengerThread = new Thread(passenger);
passengerThread.start();
}
}
}
3. Output: Concurrency access to resources using CountDownLatch(java /example)
Number of friends planned for trip: 7
Passenger 1 has boarded the cab
Passenger 4 has boarded the cab
Passenger 2 has boarded the cab
Passenger 5 has boarded the cab
Passenger 7 has boarded the cab
Passenger 6 has boarded the cab
Passenger 3 has boarded the cab
All friends has boarded the cab. Let's start the journey