1 24 package org.riotfamily.cachius.support; 25 26 import java.util.LinkedList ; 27 28 33 public class ReaderWriterLock { 34 35 private int activeReaders; 36 private int waitingReaders; 37 private int activeWriters; 38 39 private final LinkedList writerLocks = new LinkedList (); 40 41 45 public synchronized void lockForReading() { 46 if (activeWriters == 0 && writerLocks.size() == 0) { 47 ++activeReaders; 48 } 49 else { 50 ++waitingReaders; 51 try { 52 wait(); 53 } 54 catch (InterruptedException e) { 55 } 56 } 57 } 58 59 60 66 public synchronized boolean tryLockForReading() { 67 if (activeWriters == 0 && writerLocks.size() == 0) { 68 ++activeReaders; 69 return true; 70 } 71 return false; 72 } 73 74 75 78 public synchronized void releaseReaderLock() { 79 if (--activeReaders == 0) { 80 notifyFirstWriter(); 81 } 82 } 83 84 85 91 public void lockForWriting() { 92 Object lock = new Object (); 93 synchronized (lock) { 94 synchronized (this) { 95 boolean canWrite = writerLocks.size() == 0 96 && activeReaders == 0 && activeWriters == 0; 97 98 if (canWrite) { 99 ++activeWriters; 100 return; 101 } 102 writerLocks.addLast(lock); 103 } 104 try { 105 lock.wait(); 106 } 107 catch (InterruptedException e) { 108 } 109 } 110 } 111 112 113 116 public synchronized boolean tryLockForWriting() { 117 if (writerLocks.size() == 0 && activeReaders == 0 118 && activeWriters == 0) { 119 120 ++activeWriters; 121 return true; 122 } 123 return false; 124 } 125 126 127 128 131 public synchronized void releaseWriterLock() { 132 --activeWriters; 133 if (waitingReaders > 0) { 134 notifyReaders(); 135 } 136 else { 137 notifyFirstWriter(); 138 } 139 } 140 141 142 145 private void notifyReaders() { 146 activeReaders += waitingReaders; 147 waitingReaders = 0; 148 notifyAll(); 149 } 150 151 154 private void notifyFirstWriter() { 155 if (writerLocks.size() > 0) { 156 Object oldest = writerLocks.removeFirst(); 157 ++activeWriters; 158 synchronized (oldest) { 159 oldest.notify(); 160 } 161 } 162 } 163 164 } 165 | Popular Tags |