Here is my attempt to implement a simple counting semaphore in Java. Please share your comments.
/*
* A simple counting semaphore implementation.
* Acquire calls block until a resource is available.
* Supports fairness option which serves Acquire calls
* in FIFO order.
*/
import java.util.Deque;
import java.util.ArrayDeque;
public class MySemaphore {
private final int capacity;
private int usedCount;
private final boolean isFair;
private Deque<Long> waitList;
public MySemaphore(int capacity, boolean isFair) {
this.capacity = capacity;
this.isFair = isFair;
if(isFair) {
waitList = new ArrayDeque<>();
}
}
public synchronized void acquire() {
if(isFair)
waitList.addLast(Thread.currentThread().getId());
while(!(isResourceAvailable() && isEligibleToAcquire())) {
try {
wait();
} catch(InterruptedException e) {
}
}
usedCount++;
if(isFair)
waitList.removeFirst();
}
public synchronized void release() {
if (usedCount > 0) {
usedCount--;
notifyAll();
}
}
private boolean isResourceAvailable() {
return usedCount < capacity;
}
private boolean isEligibleToAcquire() {
if(!isFair)
return true;
// True only if current thread is at the head of the queue.
return Thread.currentThread().getId() == waitList.getFirst();
}
}
What happens to the intrinsic lock when interrupt is caught in the below block? My understanding is, the thread which catches the exception will still hold the lock. Please clarify.
while(!(isResourceAvailable() && isEligibleToAcquire())) {
try {
wait();
} catch(InterruptedException e) {
}
}