/* * 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(); } } }