Main Page   Packages   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

MainReadWriteLock.java

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  * @observable
00075  *   EXP notEqual (ReaderLock rl1, ReaderLock rl2): rl1 != rl2;
00076  */
00077 class ReaderLock extends Signaller implements Sync {
00078     WriterPreferenceReadWriteLock wprw;
00079     public ReaderLock(WriterPreferenceReadWriteLock wprw) {
00080         this.wprw = wprw;
00081     }
00082     /**
00083       * @observable
00084       *   RETURN successfully(this);
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  * @observable
00156  *   EXP notEqual (WriterLock wl1, WriterLock wl2): wl1 != wl2;
00157  */
00158 class WriterLock extends Signaller implements Sync {
00159     WriterPreferenceReadWriteLock wprw;
00160     public WriterLock(WriterPreferenceReadWriteLock wprw) {
00161         this.wprw = wprw;
00162     }
00163     /**
00164       * @observable
00165       *   RETURN successfully(this);
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 }

Generated at Thu Feb 7 06:50:15 2002 for Bandera by doxygen1.2.10 written by Dimitri van Heesch, © 1997-2001