package education.jtrainer.javainterviewquestions; import java.util.concurrent.Semaphore; import java.util.Random; /** * * @author Diego Gabriele */ public class ResizableSemaphore extends Semaphore{ int originalPermits; public ResizableSemaphore(int permits) { super(permits); originalPermits=permits; } @Override protected void reducePermits(int reduction) { super.reducePermits(reduction); } public int usedPermits() { return originalPermits - availablePermits(); } @Override public void release(int i){ super.release(i); } static class MyBuyer extends Thread { ResizableSemaphore semaphore; String name = ""; int totalCashiers; //this is the number of the total number of cashiers allocated by the shop manager MyBuyer(String name, ResizableSemaphore semaphore) { this.name = name; this.semaphore=semaphore; } public void run() { try { totalCashiers=semaphore.usedPermits()+semaphore.availablePermits(); System.out.println(name + ": trying to pay groceries..."); System.out.println(name + ": available cashiers: " + semaphore.availablePermits()+" total cashiers: "+totalCashiers); System.out.println(name + ": there are "+semaphore.getQueueLength() + " people in the lane waiting to pay their goods who precede me"); if (semaphore.getQueueLength() >=2) { System.out.println("too many people in the lane, manager will allocate another cashier"); semaphore.release(1); System.out.println("Available cashiers are now: " + semaphore.availablePermits()); } semaphore.acquire(); System.out.println(name + " :got the permit to pay goods!"); try { for (int i = 1; i <= 5; i++) { totalCashiers=semaphore.usedPermits()+semaphore.availablePermits(); System.out.println(name + ": I am paying good n." + i + ", available cashiers: "+ semaphore.availablePermits() +" total cashiers: "+totalCashiers); // sleep 5000 ms - this is the time needded to pay Thread.sleep(5000); } } finally { // calling release() after succesfully paying the groceries System.out.println(name + ": releasing lock..., cashier is available now to serve a new customer"); semaphore.release(); System.out.println(name + ": available cashiers now: " + semaphore.availablePermits()); // when the queue length get reduces the manager deallocates the cashier if (semaphore.getQueueLength() <=1 && semaphore.availablePermits()>2 ){ semaphore.reducePermits(1); System.out.println("manager removed cashier"); System.out.println(name + ": available cashiers: " + semaphore.availablePermits()); } } } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { System.out.println("This is the ResizableSemaphore tutorial"); ResizableSemaphore semaphore=new ResizableSemaphore(2); MyBuyer t1 = new MyBuyer("Anna",semaphore); t1.start(); Thread.sleep(new Random().nextInt(10000)); MyBuyer t2 = new MyBuyer("Bob",semaphore); t2.start(); Thread.sleep(new Random().nextInt(10000)); MyBuyer t3 = new MyBuyer("Charlie",semaphore); t3.start(); Thread.sleep(new Random().nextInt(10000)); MyBuyer t4 = new MyBuyer("Don",semaphore); t4.start(); Thread.sleep(new Random().nextInt(10000)); MyBuyer t5 = new MyBuyer("Eric",semaphore); t5.start(); Thread.sleep(new Random().nextInt(10000)); MyBuyer t6 = new MyBuyer("Fred",semaphore); t6.start(); } }