- We use ReentrantLock for locking the Resource(totalSeats)
- Incase anything goes wrong (Exception being thrown etc.) you want to make sure the lock is released no matter what.
- Calling the reserveSeats method should be done inside separate threads
ReservationSystem.java
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReservationSystem {
private Integer totalSeats;
private final Lock lock = new ReentrantLock();
public ReservationSystem(Integer totalSeats){
this.totalSeats = totalSeats;
}
public Integer getTotalSeats(){
return totalSeats;
}
public void reserveSeats(String userName, int numOfSeats){
lock.lock();
try{
if(numOfSeats >0 && totalSeats>numOfSeats){
totalSeats -= numOfSeats;
System.out.println(userName + " has reserved "+ numOfSeats + " with " + totalSeats + " still available");
}else{
System.out.println("Seats not Available");
}
}finally {
lock.unlock();
}
}
}
BookSeat.java
public class BookSeat {
public static void main(String[] args) {
ReservationSystem objResSys = new ReservationSystem(100);
System.out.println("Total available Seats "+ objResSys.getTotalSeats());
Thread objThread1 = new Thread(() -> {objResSys.reserveSeats("User1", 10);});
Thread objThread2 = new Thread(() -> {objResSys.reserveSeats("User2", 20);});
Thread objThread3 = new Thread(() -> {objResSys.reserveSeats("User3", 5);});
objThread1.start();
objThread2.start();
objThread3.start();
try {
objThread1.join();
objThread2.join();
objThread3.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Remaining available Seats "+ objResSys.getTotalSeats());
}
}
Total available Seats 100 User2 has reserved 20 with 80 still available User1 has reserved 10 with 70 still available User3 has reserved 5 with 65 still available Remaining available Seats 65