/** * Copyright (c): Uwe Schmidt, FH Wedel * * You may study, modify and distribute this source code * FOR NON-COMMERCIAL PURPOSES ONLY. * This copyright message has to remain unchanged. * * Note that this document is provided 'as is', * WITHOUT WARRANTY of any kind either expressed or implied. */ /** a Test for synchronised * access of a buffer with 2 variables * and sequential producer consumer access */ //---------------- class Resource { // the empty/full flag public boolean empty = true; public int i,j; public Resource() { i = 0; j = 0; } } //---------------- public class SyncTest { // the shared global resource buffer // used by both threads // both buffer variables i and j // always contain the same value public static Resource buffer = new Resource(); //---------------- // the main method public static void main(String[] argv) { Thread producer = new Producer(buffer); Thread consumer = new Consumer(buffer); producer.setName("producer"); consumer.setName("consumer"); producer.start(); consumer.start(); } } //---------------- abstract class SleepyThread extends Thread { public void sleepAWhile() { try { sleep( (int)(Math.random() * 500) ); } catch ( InterruptedException e ) { } } //---------------- public abstract void doIt(); //---------------- public void run() { System.out.println(getName() + " started"); for (int i = 0; i < 10; ++ i ) { doIt(); sleepAWhile(); } System.out.println(getName() + " finished"); } } //---------------- class Producer extends SleepyThread { // the shared buffer private Resource buffer; public Producer(Resource buffer) { super(); this.buffer = buffer; } //---------------- public void doIt() { synchronized ( buffer ) { while ( ! buffer.empty ) { // producer must wait until buffer empty try { System.out.println(getName() + " waiting"); buffer.wait(); } catch ( InterruptedException e ) { } System.out.println(getName() + " notified"); } System.out.println(getName() + " incrementing i"); // modify 1. variable ++ buffer.i; // simulate some complex computations sleepAWhile(); System.out.println(getName() + " incrementing j"); // modify 2. variable ++ buffer.j; buffer.empty = false; buffer.notify(); } } } //---------------- class Consumer extends SleepyThread { // the shared buffer private Resource buffer; public Consumer(Resource buffer) { super(); this.buffer = buffer; } //---------------- public void doIt() { synchronized ( buffer ) { int i,j; while ( buffer.empty ) { // consumer must wait until buffer is full try { System.out.println(getName() + " waiting"); buffer.wait(); } catch ( InterruptedException e ) { } System.out.println(getName() + " notified"); } System.out.println(getName() + " reading i"); // read 1. variable i = buffer.i; // simulate some complex computations sleepAWhile(); System.out.println(getName() + " reading j"); // reading 2. variable j = buffer.j; System.out.println(getName() + " i,j = " + i + "," + j); buffer.empty = true; buffer.notify(); } } }