import java.text.DecimalFormat; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SharedCell extends JFrame { JTextArea output = new JTextArea( 20, 30 ); public SharedCell() { super( "Demonstrating Thread Synchronization" ); getContentPane().add( new JScrollPane( output ) ); setSize( 500, 500 ); show(); // set up threads and start threads HoldIntegerSynchronized h = new HoldIntegerSynchronized( this ); ProduceInteger p = new ProduceInteger( h, this ); ConsumeInteger c = new ConsumeInteger( h, this ); p.start(); c.start(); } void show(String s) { output.append(s); System.out.print(s); } public static void main( String args[] ) { SharedCell app = new SharedCell(); app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } }
import javax.swing.JTextArea; public class ProduceInteger extends Thread { private HoldIntegerSynchronized pHold; private SharedCell output; public ProduceInteger( HoldIntegerSynchronized h, SharedCell o ) { super( "ProduceInteger" ); pHold = h; output = o; } public void run() { for ( int count = 1; count <= 10; count++ ) { // sleep for a random interval // Note: Interval shortened purposely to fill buffer try { Thread.sleep( (int) ( Math.random() * 500 ) ); } catch( InterruptedException e ) { System.err.println( e.toString() ); } pHold.setSharedInt( count ); } output.show( "\n" + getName() + " finished producing values" + "\nTerminating " + getName() ); } }
// ConsumeInteger.java // Definition of threaded class ConsumeInteger import javax.swing.JTextArea; public class ConsumeInteger extends Thread { private HoldIntegerSynchronized cHold; private SharedCell output; public ConsumeInteger( HoldIntegerSynchronized h, SharedCell o ) { super( "ConsumeInteger" ); cHold = h; output = o; } public void run() { int val, sum = 0; do { // sleep for a random interval try { Thread.sleep( (int) ( Math.random() * 3000 ) ); } catch( InterruptedException e ) { System.err.println( e.toString() ); } val = cHold.getSharedInt(); sum += val; } while ( val != 10 ); output.show( "\n" + getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() + "\n" ); } }
import javax.swing.JTextArea; import java.text.DecimalFormat; public class HoldIntegerSynchronized { private int sharedInt[] = { -1, -1, -1, -1, -1 }; private boolean writeable = true; private boolean readable = false; private int readLoc = 0, writeLoc = 0; private SharedCell output; public HoldIntegerSynchronized( SharedCell o ) { output = o; } public synchronized void setSharedInt( int val ) { while ( !writeable ) { try { output.show( " WAITING TO PRODUCE " + val ); wait(); } catch ( InterruptedException e ) { System.err.println( e.toString() ); } } sharedInt[ writeLoc ] = val; readable = true; output.show( "\nProduced " + val + " into cell " + writeLoc ); writeLoc = ( writeLoc + 1 ) % 5; output.show( "\twrite " + writeLoc + "\tread " + readLoc); displayBuffer( output, sharedInt ); if ( writeLoc == readLoc ) { writeable = false; output.show( "\nBUFFER FULL" ); } notify(); } public synchronized int getSharedInt() { int val; while ( !readable ) { try { output.show( " WAITING TO CONSUME" ); wait(); } catch ( InterruptedException e ) { System.err.println( e.toString() ); } } writeable = true; val = sharedInt[ readLoc ]; output.show( "\nConsumed " + val + " from cell " + readLoc ); readLoc = ( readLoc + 1 ) % 5; output.show( "\twrite " + writeLoc + "\tread " + readLoc ); displayBuffer( output, sharedInt ); if ( readLoc == writeLoc ) { readable = false; output.show( "\nBUFFER EMPTY" ); } notify(); return val; } public void displayBuffer( SharedCell out, int buf[] ) { DecimalFormat formatNumber = new DecimalFormat( " #;-#" ); output.show( "\tbuffer: " ); for ( int i = 0; i < buf.length; i++ ) output.show( " " + formatNumber.format( buf[ i ] )); } }
Produced 1 into cell 0 write 1 read 0 buffer: 1 -1 -1 -1 -1 Produced 2 into cell 1 write 2 read 0 buffer: 1 2 -1 -1 -1 Produced 3 into cell 2 write 3 read 0 buffer: 1 2 3 -1 -1 Consumed 1 from cell 0 write 3 read 1 buffer: 1 2 3 -1 -1 Produced 4 into cell 3 write 4 read 1 buffer: 1 2 3 4 -1 Produced 5 into cell 4 write 0 read 1 buffer: 1 2 3 4 5 Produced 6 into cell 0 write 1 read 1 buffer: 6 2 3 4 5 BUFFER FULL WAITING TO PRODUCE 7 Consumed 2 from cell 1 write 1 read 2 buffer: 6 2 3 4 5 Produced 7 into cell 1 write 2 read 2 buffer: 6 7 3 4 5 BUFFER FULL WAITING TO PRODUCE 8 Consumed 3 from cell 2 write 2 read 3 buffer: 6 7 3 4 5 Produced 8 into cell 2 write 3 read 3 buffer: 6 7 8 4 5 BUFFER FULL WAITING TO PRODUCE 9 Consumed 4 from cell 3 write 3 read 4 buffer: 6 7 8 4 5 Produced 9 into cell 3 write 4 read 4 buffer: 6 7 8 9 5 BUFFER FULL WAITING TO PRODUCE 10 Consumed 5 from cell 4 write 4 read 0 buffer: 6 7 8 9 5 Produced 10 into cell 4 write 0 read 0 buffer: 6 7 8 9 10 BUFFER FULL ProduceInteger finished producing values Terminating ProduceInteger Consumed 6 from cell 0 write 0 read 1 buffer: 6 7 8 9 10 Consumed 7 from cell 1 write 0 read 2 buffer: 6 7 8 9 10 Consumed 8 from cell 2 write 0 read 3 buffer: 6 7 8 9 10 Consumed 9 from cell 3 write 0 read 4 buffer: 6 7 8 9 10 Consumed 10 from cell 4 write 0 read 0 buffer: 6 7 8 9 10 BUFFER EMPTY ConsumeInteger retrieved values totaling: 55 Terminating ConsumeInteger |
Maintained by John Loomis, last updated 15 July 2000