/*
* Mutex.java
*
* Created on August 26, 2006, 7:31 PM
*
* From "The Art of Multiprocessor Programming",
* by Maurice Herlihy and Nir Shavit.
* Copyright 2006 Elsevier Inc. All rights reserved.
*/
package monitor;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.TimeUnit;
/**
* Non-Reentrant mutual exclusion lock based on AbstractQueuedSynchronizer.
* @author Maurice Herlihy
*/
class Mutex implements Lock {
final static int FREE = 0;
final static int BUSY = 1;
// Inner helper class
private static class LockSynch extends AbstractQueuedSynchronizer {
// Report whether in locked state
protected boolean isHeldExclusively() {
return getState() == BUSY;
}
// Acquire the lock if state is FREE
public boolean tryAcquire(int acquires) {
return compareAndSetState(FREE, BUSY);
}
// Release the lock by setting state to FREE
protected boolean tryRelease(int releases) {
if (getState() == FREE)
throw new IllegalMonitorStateException();
setState(FREE);
return true;
}
// Provide a Condition
Condition newCondition() {
return new ConditionObject();
}
}
// The sync object does all the hard work. We just forward to it.
private final LockSynch sync = new LockSynch();
public void lock() {
sync.acquire(0);
}
public boolean tryLock() {
return sync.tryAcquire(0);
}
public void unlock() {
sync.release(0);
}
public Condition newCondition() {
return sync.newCondition();
}
public boolean isLocked() {
return sync.isHeldExclusively();
}
public boolean hasQueuedThreads() {
return sync.hasQueuedThreads();
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(0);
}
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}
}