/*
* FIFOReadWriteLock.java
*
* Created on January 9, 2006, 7:39 PM
*
* From "Multiprocessor Synchronization and Concurrent Data Structures",
* by Maurice Herlihy and Nir Shavit.
* Copyright 2006 Elsevier Inc. All rights reserved.
*/
package monitor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* First-in First-out readers/writers lock.
* @author Maurice Herlihy
*/
public class FifoReadWriteLock implements ReadWriteLock {
int readAcquires; // read acquires since start
int readReleases; // read releses since start
boolean writer; // writer present?
Lock metaLock; // short-term synchronization
Condition condition;
Lock readLock; // readers apply here
Lock writeLock; // writers apply here
public FifoReadWriteLock() {
readAcquires = readReleases = 0;
writer = false;
metaLock = new ReentrantLock();
condition = metaLock.newCondition();
readLock = new ReadLock();
writeLock = new WriteLock();
}
public Lock readLock() {
return readLock;
}
public Lock writeLock() {
return writeLock;
}
private class ReadLock implements Lock {
public void lock() {
metaLock.lock();
try {
readAcquires++;
while (writer) {
try {
condition.await();
} catch (InterruptedException ex) {
// do something application-specific
}
}
} finally {
metaLock.unlock();
}
}
public void unlock() {
metaLock.lock();
try {
readReleases++;
if (readAcquires == readReleases)
condition.signalAll();
} finally {
metaLock.unlock();
}
}
public void lockInterruptibly() throws InterruptedException {
throw new UnsupportedOperationException();
}
public boolean tryLock() {
throw new UnsupportedOperationException();
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
throw new UnsupportedOperationException();
}
public Condition newCondition() {
throw new UnsupportedOperationException();
}
}
private class WriteLock implements Lock {
public void lock() {
metaLock.lock();
try {
while (readAcquires != readReleases)
try {
condition.await();
} catch (InterruptedException e) {}
writer = true;
} finally {
metaLock.unlock();
}
}
public void unlock() {
writer = false;
}
public void lockInterruptibly() throws InterruptedException {
throw new UnsupportedOperationException();
}
public boolean tryLock() {
throw new UnsupportedOperationException();
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
throw new UnsupportedOperationException();
}
public Condition newCondition() {
throw new UnsupportedOperationException();
}
}
}