import java.util.LinkedList; import java.lang.Exception; public class ReaderWriterLock { private volatile int activeReaders = 0; private volatile int waitingReaders = 0; private volatile int activeWriters = 0; private volatile int waitingWriters = 0; private final LinkedList _waitQueue = new LinkedList(); private final LinkedList _threads = new LinkedList(); public synchronized void startRead() { if (!(activeReaders > 0 && _threads.contains(Thread.currentThread()))) { //makes sure that a reader is not called twice if (_threads.contains(Thread.currentThread())) throw new DeadlockException(); if (waitingWriters> 0 || activeWriters > 0) { waitingReaders++; Reader r = new Reader(); r.waitThread(); } } _threads.add(Thread.currentThread()); waitingReaders--; activeReaders++; } public synchronized void endRead(){ activeReaders--; _threads.remove(Thread.currentThread()); if (activeReaders == 0) notifyReaderWriter(); } public synchronized void startWrite() { if (_threads.contains(Thread.currentThread())) { //makes sure that the write is not called twice or else deadlock throw new DeadlockException(); } if ( activeReaders > 0 || activeWriters > 0 || waitingReaders > 0 || waitingWriters> 0) { waitingWriters++; Writer w = new Writer(); w.waitThread(); } waitingWriters--; activeWriters++; _threads.add(Thread.currentThread()); } public synchronized void endWrite(){ activeWriters--; _threads.remove(Thread.currentThread()); notifyReaderWriter(); } private synchronized void notifyReaderWriter() { while(_waitQueue.size()>0) { ReadWrite front = (ReadWrite)_waitQueue.getFirst(); if(front.name().equals("reader")) front.startThread(); // removes front from queue if(front.name().equals("writer")) { //front is a writer front.startThread(); break; } } } public abstract class ReadWrite{ private volatile boolean wait = true; public abstract String name(); public void waitThread() { synchronized(ReaderWriterLock.this) { wait = true; _waitQueue.addLast(this); while (wait) { try { ReaderWriterLock.this.wait(); } catch (InterruptedException e) { } } } } public void startThread() { synchronized(ReaderWriterLock.this) { wait = false; _waitQueue.removeFirst(); ReaderWriterLock.this.notifyAll(); } } } public class Reader extends ReadWrite { public String name() { return "reader";} } public class Writer extends ReadWrite { public String name() {return "writer";} } public static class DeadlockException extends IllegalStateException { public DeadlockException() { } public DeadlockException(String s) { super(s); } public DeadlockException(String s, Throwable t) { super(s,t); } public DeadlockException(Throwable t) { super(t); } } }