/*********************************************************************** * Tom Kelliher * CS 245 * Synch1.java * * This applet is a first pass at demonstrating the classic producer * consumer problem. The producer produces 10 integer values and * forms their sum. These values are stored in an intermediate queue * of depth one with absolutely no synchronization control. The values * are consumed by the consumer, which also forms their sum. In this * model, it is assumed that the producer needs 1000 ms. to produce a * value and the consumer needs 2000 ms. to consume a value. Further, * there is no explicit signal from producer to consumer indicating the * production has ceased. ***********************************************************************/ import java.applet.*; import java.awt.*; /*********************************************************************** * class Synch1 ***********************************************************************/ public class Synch1 extends Applet { Display display = new Display(); Queue que = new Queue(0, display); // producer and consumer are threads. Producer producer = new Producer(display, que); Consumer consumer = new Consumer(display, que); public void init() { add(display); producer.start(); consumer.start(); } } /*********************************************************************** * class Display --- Used to display current produced/consumed value as * well as the producer's and consumer's sums. ***********************************************************************/ class Display extends Panel { private Label producer = new Label("Producer"); private Label consumer = new Label("Consumer"); private Label current = new Label("Current Value"); private Label sum = new Label("Sum"); public Label prodCur = new Label("Empty"); public Label prodSum = new Label("Empty"); public Label conCur = new Label("Empty"); public Label conSum = new Label("Empty"); public Display() { setLayout(new GridLayout(3, 3)); add(new Panel()); add(producer); add(consumer); add(current); add(prodCur); add(conCur); add(sum); add(prodSum); add(conSum); } } /*********************************************************************** * class Producer --- Producer thread. Display d is the Display object * to use for displaying sum. Queue q is the queue to which * production is stored. ***********************************************************************/ class Producer extends Thread { private Display disp; private Queue que; public Producer(Display d, Queue q) { disp = d; que = q; } public void run() { int i; int sum = 0; for (i = 0; i < 10; ++i) // Produce 10 values. { sum += i; disp.prodSum.setText("" + sum); que.put(i); try { sleep(1000); } catch (Exception e) { } } disp.prodSum.setText("Final: " + sum); } } /*********************************************************************** * class Consumer --- Consumer thread. Display d is the Display object * to use for displaying sum. Queue q is the queue from which * we consume. ***********************************************************************/ class Consumer extends Thread { private Display disp; private Queue que; public Consumer(Display d, Queue q) { disp = d; que = q; } public void run() { int val; int sum = 0; while (true) // Consume indefinitely. { try { sleep(2000); } catch (Exception e) { } val = que.get(); sum += val; disp.conSum.setText("" + sum); } } } /*********************************************************************** * class Queue --- The depth one storage buffer between producer and * consumer. int v is the initial stored value, in case the consumer * consumes before the producer produces. This is our one * accommodation of synchronization. Display d is the display used * for displaying the produced or consumed values. ***********************************************************************/ class Queue { private int val; private Display disp; public Queue(int v, Display d) { val = v; disp = d; } // Produce into the queue. public void put(int v) { disp.prodCur.setText("" + v); val = v; } // Consume from the queue. public int get() { disp.conCur.setText("" + val); return val; } }