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