00001 public class MainReadWriteLock {
00002 public static void main(String[] args) {
00003 ReadWriteLock rw = new WriterPreferenceReadWriteLock();
00004 new ReaderThread(rw).start();
00005 new WriterThread(rw).start();
00006 new WriterThread(rw).start();
00007 }
00008 }
00009 class ReaderThread extends Thread {
00010 Reader r;
00011 public ReaderThread(ReadWriteLock rw) {
00012 r = new Reader(rw);
00013 }
00014 public void run() {
00015 while (true) {
00016 try {
00017 r.read();
00018 } catch (InterruptedException e) {
00019 }
00020 }
00021 }
00022 }
00023 class Reader {
00024 ReadWriteLock rw;
00025 public Reader(ReadWriteLock rw) {
00026 this.rw = rw;
00027 }
00028 public void read() throws InterruptedException {
00029 rw.readLock().acquire();
00030 System.out.println("Start reading...");
00031 System.out.println("Finish reading...");
00032 rw.readLock().release();
00033 }
00034 }
00035 class WriterThread extends Thread {
00036 Writer w;
00037 public WriterThread(ReadWriteLock rw) {
00038 w = new Writer(rw);
00039 }
00040 public void run() {
00041 while (true) {
00042 try {
00043 w.write();
00044 } catch (InterruptedException e) {
00045 }
00046 }
00047 }
00048 }
00049 class Writer {
00050 ReadWriteLock rw;
00051 public Writer(ReadWriteLock rw) {
00052 this.rw = rw;
00053 }
00054 public void write() throws InterruptedException {
00055 rw.writeLock().acquire();
00056 System.out.println("Start writing...");
00057 System.out.println("Finish writing...");
00058 rw.writeLock().release();
00059 }
00060 }
00061 interface Sync {
00062 public void acquire() throws InterruptedException;
00063 public boolean attempt(int msecs) throws InterruptedException;
00064 public void release();
00065 }
00066 interface ReadWriteLock {
00067 Sync readLock();
00068 Sync writeLock();
00069 }
00070 abstract class Signaller {
00071 abstract void signalWaiters();
00072 }
00073
00074
00075
00076
00077 class ReaderLock extends Signaller implements Sync {
00078 WriterPreferenceReadWriteLock wprw;
00079 public ReaderLock(WriterPreferenceReadWriteLock wprw) {
00080 this.wprw = wprw;
00081 }
00082
00083
00084
00085
00086 public void acquire() throws InterruptedException {
00087 Object ie = null;
00088 synchronized (this) {
00089 if (!wprw.startReadFromNewReader()) {
00090 for (;;) {
00091 try {
00092 wait();
00093 if (wprw.startReadFromWaitingReader())
00094 return;
00095 } catch (InterruptedException ex) {
00096 wprw.cancelledWaitingReader();
00097 ie = ex;
00098 break;
00099 }
00100 }
00101 }
00102 }
00103 if (ie != null) {
00104 wprw.writerLock_.signalWaiters();
00105 throw (Throwable) ie;
00106 }
00107 }
00108 public boolean attempt(int msecs) throws InterruptedException {
00109 Object ie = null;
00110 synchronized (this) {
00111 if (msecs <= 0)
00112 return wprw.startRead();
00113 else
00114 if (wprw.startReadFromNewReader())
00115 return true;
00116 else {
00117 int waitTime = msecs;
00118 int start = System.currentTimeMillis();
00119 for (;;) {
00120 try {
00121 wait(waitTime);
00122 } catch (InterruptedException ex) {
00123 wprw.cancelledWaitingReader();
00124 ie = ex;
00125 break;
00126 }
00127 if (wprw.startReadFromWaitingReader())
00128 return true;
00129 else {
00130 waitTime = msecs - (System.currentTimeMillis() - start);
00131 if (waitTime <= 0) {
00132 wprw.cancelledWaitingReader();
00133 break;
00134 }
00135 }
00136 }
00137 }
00138 }
00139 wprw.writerLock_.signalWaiters();
00140 if (ie != null)
00141 throw (Throwable) ie;
00142 else
00143 return false;
00144 }
00145 public void release() {
00146 Signaller s = wprw.endRead();
00147 if (s != null)
00148 s.signalWaiters();
00149 }
00150 synchronized void signalWaiters() {
00151 notifyAll();
00152 }
00153 }
00154
00155
00156
00157
00158 class WriterLock extends Signaller implements Sync {
00159 WriterPreferenceReadWriteLock wprw;
00160 public WriterLock(WriterPreferenceReadWriteLock wprw) {
00161 this.wprw = wprw;
00162 }
00163
00164
00165
00166
00167 public void acquire() throws InterruptedException {
00168 Object ie = null;
00169 synchronized (this) {
00170 if (!wprw.startWriteFromNewWriter()) {
00171 for (;;) {
00172 try {
00173 wait();
00174 if (wprw.startWriteFromWaitingWriter())
00175 return;
00176 } catch (InterruptedException ex) {
00177 wprw.cancelledWaitingWriter();
00178 notify();
00179 ie = ex;
00180 break;
00181 }
00182 }
00183 }
00184 }
00185 if (ie != null) {
00186 wprw.readerLock_.signalWaiters();
00187 throw (Throwable) ie;
00188 }
00189 }
00190 public boolean attempt(int msecs) throws InterruptedException {
00191 Object ie = null;
00192 synchronized (this) {
00193 if (msecs <= 0)
00194 return wprw.startWrite();
00195 else
00196 if (wprw.startWriteFromNewWriter())
00197 return true;
00198 else {
00199 int waitTime = msecs;
00200 int start = System.currentTimeMillis();
00201 for (;;) {
00202 try {
00203 wait(waitTime);
00204 } catch (InterruptedException ex) {
00205 wprw.cancelledWaitingWriter();
00206 notify();
00207 ie = ex;
00208 break;
00209 }
00210 if (wprw.startWriteFromWaitingWriter())
00211 return true;
00212 else {
00213 waitTime = msecs - (System.currentTimeMillis() - start);
00214 if (waitTime <= 0) {
00215 wprw.cancelledWaitingWriter();
00216 notify();
00217 break;
00218 }
00219 }
00220 }
00221 }
00222 }
00223 wprw.readerLock_.signalWaiters();
00224 if (ie != null)
00225 throw (Throwable) ie;
00226 else
00227 return false;
00228 }
00229 public void release() {
00230 Signaller s = wprw.endWrite();
00231 if (s != null)
00232 s.signalWaiters();
00233 }
00234 synchronized void signalWaiters() {
00235 notify();
00236 }
00237 }
00238
00239 class WriterPreferenceReadWriteLock implements ReadWriteLock {
00240 protected int activeReaders_ = 0;
00241 protected int activeWriter_ = 0;
00242 protected int waitingReaders_ = 0;
00243 protected int waitingWriters_ = 0;
00244 protected final ReaderLock readerLock_ = new ReaderLock(this);
00245 protected final WriterLock writerLock_ = new WriterLock(this);
00246 protected boolean allowReader() {
00247 return activeWriter_ == 0 && waitingWriters_ == 0;
00248 }
00249 protected synchronized void cancelledWaitingReader() {
00250 --waitingReaders_;
00251 }
00252 protected synchronized void cancelledWaitingWriter() {
00253 --waitingWriters_;
00254 }
00255 protected synchronized Signaller endRead() {
00256 if (--activeReaders_ == 0 && waitingWriters_ > 0)
00257 return writerLock_;
00258 else
00259 return null;
00260 }
00261 protected synchronized Signaller endWrite() {
00262 activeWriter_ = 0;
00263 if (waitingReaders_ > 0 && allowReader())
00264 return readerLock_;
00265 else
00266 if (waitingWriters_ > 0)
00267 return writerLock_;
00268 else
00269 return null;
00270 }
00271 public Sync readLock() {
00272 return readerLock_;
00273 }
00274 protected synchronized boolean startRead() {
00275 boolean allowRead = allowReader();
00276 if (allowRead)
00277 ++activeReaders_;
00278 return allowRead;
00279 }
00280 protected synchronized boolean startReadFromNewReader() {
00281 boolean pass = startRead();
00282 if (!pass)
00283 ++waitingReaders_;
00284 return pass;
00285 }
00286 protected synchronized boolean startReadFromWaitingReader() {
00287 boolean pass = startRead();
00288 if (pass)
00289 --waitingReaders_;
00290 return pass;
00291 }
00292 protected synchronized boolean startWrite() {
00293 boolean allowWrite = (activeWriter_ == 0 && activeReaders_ == 0);
00294 if (allowWrite)
00295 activeWriter_ = 1;
00296 return allowWrite;
00297 }
00298 protected synchronized boolean startWriteFromNewWriter() {
00299 boolean pass = startWrite();
00300 if (!pass)
00301 ++waitingWriters_;
00302 return pass;
00303 }
00304 protected synchronized boolean startWriteFromWaitingWriter() {
00305 boolean pass = startWrite();
00306 if (pass)
00307 --waitingWriters_;
00308 return pass;
00309 }
00310 public Sync writeLock() {
00311 return writerLock_;
00312 }
00313 }