// // $Source: /home/cur/djb1/java/threads/RCS/CHAN_OF_INT.java,v $ // // $Id: CHAN_OF_INT.java,v 1.1 1996/10/02 15:19:28 djb1 Exp $ // // CHAN_OF_INT class - an occam CHAN OF INT for multiple readers and writers. // // (C) Copyright 1996 Peter Welch and // Dave Beckett // University of Kent at Canterbury // import java.lang.InterruptedException; //{{{ description (javadoc format) /** * Channel extends an occam CHAN OF INT for multiple readers and writers. * * There is full synchronisation between a reading and writing thread. Any * thread may read or write on this channel. Readers and writers are queued * separately. A reader only completes when it gets to the front of its queue * and finds a writer. A writer only completes when it gets to the front of * its queue and finds a reader. *

* There is no logical buffering of data in the channel however each int * is actually copied three times with this implementation. * *@version $Revision: 1.1 $ *@author Peter Welch, P.H.Welch@ukc.ac.uk *@author Dave Beckett, D.J.Beckett@ukc.ac.uk */ //}}} class CHAN_OF_INT { //{{{ private member data private int channel_hold; // buffer (not detectable to users) private boolean channel_empty = true; // synchronisation flag Object read_monitor = // all readers multiplex through this new Object (); Object write_monitor = // all writers multiplex through this new Object (); //}}} //{{{ read method /** * read method: read an int from the channel. This method * blocks until a corresponding thread calls the write method, * at which point a rendezvous is formed and the data is passed. * *@return the object sent from the writing thread. * *@exception InterruptedException * Occurs if the wait methods are interrupted. */ public int read () throws InterruptedException { synchronized (read_monitor) { synchronized (this) { if (channel_empty) { channel_empty = false; // first to the rendezvous wait (); // wait for the writer thread notify (); // schedule the writer to finish } else { channel_empty = true; // second to the rendezvous notify (); // schedule the waiting writer thread } return channel_hold; } } } //}}} //{{{ write method /** * write method: write an int to the channel. This method * blocks until a corresponding thread calls the read method, * at which point a rendezvous is formed and the data is passed. * *@param n the int to be sent to the reading thread. * *@exception InterruptedException * Occurs if the wait methods are interrupted. */ public void write (int n) throws InterruptedException { synchronized (write_monitor) { synchronized (this) { channel_hold = n; if (channel_empty) { channel_empty = false; // first to the rendezvous wait (); // wait for the reader thread } else { channel_empty = true; // second to the rendezvous notify (); // schedule the waiting reader thread wait (); // let the reader regain this monitor } } } } //}}} //{{{ is_empty method /** * is_empty method: determine whether a thread is waiting at the * other end of the channel. This can be used either at the writing or the * reading end of the channel. * *@return true iff no thread is waiting at the other end. */ public boolean is_empty () { return channel_empty; } //}}} }