- Semaphore is used to synchronize threads.
- Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource.
- We will use binary semaphore to demonstrate the synchronization of shared resources.
- What is binary Semaphore ?
- A semaphore initialized to one, and which is used such that it only has at most one permit available. Only one permit is available to enter particular execution block.
1. Scenario: Synchronize resources using Semaphore (concurrency/example)
- We have booking agent to tickets for passengers.
- Suppose simultaneously more than one passengers approached booking agent to book their respective tickets.
- Booking agent can entertain one passenger at a time (on).
- We need to protect the concurrent access to book ticket(s), so that integrity of data is ensured.
- We will use binary semaphore to protect shared resources.
2. Program: Synchronize resources using Semaphore (concurrency/example)
2.1 BookingAgent class:
- BookingAgent class is responsible for booking tickets.
- BookingAgent class implements Runnable interface.
package org.learn.sema;
public class BookingAgent implements Runnable {
private Reservation reservation;
public BookingAgent(Reservation reservation) {
this.reservation = reservation;
}
@Override
public void run() {
System.out.println("Initiate booking for "+ Thread.currentThread().getName());
reservation.book(new Object());
System.out.println("Successfully booked ticket for "+ Thread.currentThread().getName());
}
}
2.2 Reservation class:
- Reservation class is responsible for reserving the ticket(s).
- We have used semaphore having permit count 1 (binary semaphore).
- book method of reservation class make use of acquire & release method semaphore class.
package org.learn.sema;
import java.util.Random;
import java.util.concurrent.Semaphore;
import static java.lang.Thread.sleep;
public class Reservation {
private Semaphore semaphore;
private Random random = new Random();
public Reservation() {
semaphore = new Semaphore(1);
}
public void book(Object personalInfo) {
try {
semaphore.acquire();
int duration = random.nextInt(100);
System.out.printf("Time taken to book ticket for %s : %d\n",
Thread.currentThread().getName(), duration);
sleep(duration);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
2.3 SemaphoreExample class:
- SemaphoreExample class contains main method to demonstrate semaphore construct.
- We will simulate the booking of five passengers.
- Five threads concurrency access the BookingAgent.
- BookingAgent will internally using Semaphore to synchronize resources.
package org.learn.sema;
public class SemaphoreExample {
public static void main(String[] args) throws InterruptedException {
Reservation reservation = new Reservation();
BookingAgent bookingAgent = new BookingAgent(reservation);
for (int i = 1; i <= 5; i++) {
Thread passenger = new Thread(bookingAgent, "Passenger "+i);
passenger.start();
}
}
}
3. Output: Conurrency access to resources using Semaphore (java /example)
Initiate booking for Passenger 1
Initiate booking for Passenger 3
Initiate booking for Passenger 5
Initiate booking for Passenger 4
Initiate booking for Passenger 2
Time taken to book ticket for Passenger 1 : 47
Successfully booked ticket for Passenger 1
Time taken to book ticket for Passenger 3 : 60
Successfully booked ticket for Passenger 3
Time taken to book ticket for Passenger 5 : 78
Successfully booked ticket for Passenger 5
Time taken to book ticket for Passenger 4 : 64
Successfully booked ticket for Passenger 4
Time taken to book ticket for Passenger 2 : 67
Successfully booked ticket for Passenger 2