/*File Synch01.java Copyright 1997, R.G.Baldwin This program illustrates the Producer/Consumer model using wait() and notify() Tested using JDK 1.1.3 under Win95. The output for one particular run of the program was: Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue full, waiting Queue full, waiting Queue full, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Queue empty, waiting Terminating Consumer run method Terminating Producer run method **********************************************************/ class Synch01{ //Instantiate a class object named QueueManager which // will manage the producer/consumer model. static QueueManager queueManager = new QueueManager(); //used to tell the threads to terminate static boolean running = true; public static void main(String[] args){ //instantiate and start two threads Thread producer = new Producer(); Thread consumer = new Consumer(); producer.start(); consumer.start(); try{ //delay two seconds Thread.currentThread().sleep(2000); }catch(InterruptedException e){}; running = false;//signal the threads to terminate }//end main }//end class Synch01 //=======================================================// class Producer extends Thread { //producer thread public void run() { //run method for Producer thread byte byteToStore; //used to store data to be enqueued //Loop until running goes false while (Synch01.running){ //get a data byte byteToStore = (byte)(Math.random()*128); //Invoke the synchronized method to put the byte // in the queue Synch01.queueManager.putByteInQueue(byteToStore); //delay a random period of time try{ Thread.currentThread().sleep( (int)(Math.random()*100)); }catch(InterruptedException e){}; }//end while statement System.out.println("Terminating Producer run method"); }//end run method }//end class producer //=======================================================// class Consumer extends Thread { //consumer thread public void run() { //run method for Consumer thread //used to store the data read from the queue byte dataFromQueue; //Loop until running goes false while (Synch01.running) { //Invoke the synchronized method to get a byte // from the queue dataFromQueue = Synch01.queueManager.getByteFromQueue(); //delay a random amount of time try{ Thread.currentThread().sleep( (int)(Math.random()*100)); }catch(InterruptedException e){}; }//end while statement System.out.println("Terminating Consumer run method"); }//end run method }//end class consumer //=======================================================// //This class implements the Producer/Consumer model by // managing a queue as a shared resource. class QueueManager{ Queue queue; //-------------------------------------------------------// QueueManager(){//constructor queue = new Queue();//instantiate a queue object }//end constructor //-------------------------------------------------------// synchronized void putByteInQueue(byte incomingByte){ //This synchronized method places a byte in the queue // If the queue is full, wait(). If still full when // wait() terminates, wait again. Called by the // producer thread to put a byte in the queue. try{ while(queue.isFull()){ System.out.println("Queue full, waiting"); wait(); }//end while loop }catch (InterruptedException E){ System.out.println("InterruptedException: " + E); }//end catch block //put the byte into the queue queue.enQueue(incomingByte); //wake up getByteFromQueue() if it has invoked wait(). notify(); }//end method putByteInQueue() //-----------------------------------------------------// public synchronized byte getByteFromQueue(){ //This synchronized method removes a byte from the // queue. If the queue is empty, wait(). If still // empty when wait() terminates, wait again. Called by // consumer thread to get a byte from the queue try{ while(queue.isEmpty()){ System.out.println("Queue empty, waiting"); wait(); }// end while }catch (InterruptedException E){ System.out.println("InterruptedException: " + E); }//end catch block //get the byte from the queue byte data = queue.deQueue(); //wake up putByteInQueue() if it has invoked wait(). notify(); return data; }//end getByteFromQueue() }//end class QueueManager //=======================================================// //This is a standard FIFO queue class. class Queue{ //constant defining maximum queue size static final int MAXQUEUE = 4; byte[] queue = new byte[MAXQUEUE]; int front, rear; Queue(){//constructor front = rear = 0; }//end constructor void enQueue(byte item){ queue[rear] = item; rear = next(rear); }//end method enQueue byte deQueue(){ byte temp = queue[front]; front = next(front); return temp; }//end method deQueue boolean isEmpty(){ return front == rear; }//end isEmpty boolean isFull(){ return (next(rear) == front); }//end isFull int next(int index){ return (index+1 < MAXQUEUE ? index+1 : 0); }//end next }//end Queue class //=======================================================// |