Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Java threads
Threaded class extends thread
Synchronized class is a monitor
Runnable interface gives thread methods
All code is
(C) Copyright 1999 by Deitel & Associates,
Inc. and Prentice Hall.
ThreadTester.java
// Fig. 15.3: ThreadTester.java
// Show multiple threads printing at different intervals.
public class ThreadTester {
public static void main( String args[] )
{
PrintThread thread1, thread2, thread3, thread4;
thread1 = new PrintThread( "thread1" );
thread2 = new PrintThread( "thread2" );
thread3 = new PrintThread( "thread3" );
thread4 = new PrintThread( "thread4" );
System.err.println( "\nStarting threads" );
thread1.start();
thread2.start();
thread3.start();
thread4.start();
System.err.println( "Threads started\n" );
}
}
class PrintThread extends Thread
class PrintThread extends Thread {
private int sleepTime;
// PrintThread constructor assigns name to thread
// by calling Thread constructor
public PrintThread( String name )
{
super( name );
// sleep between 0 and 5 seconds
sleepTime = (int) ( Math.random() * 5000 );
System.err.println( "Name: " + getName() +
"; sleep: " + sleepTime );
}
execute the thread
// execute the thread
public void run()
{
// put thread to sleep for a random interval
try {
System.err.println( getName() + " going to sleep" );
Thread.sleep( sleepTime );
}
catch ( InterruptedException exception ) {
System.err.println( exception.toString() );
}
// print thread name
System.err.println( getName() + " done sleeping" );
}
}
ConsumeInteger.java
// Fig. 15.4: ConsumeInteger.java
// Definition of threaded class ConsumeInteger
public class ConsumeInteger extends Thread {
private HoldIntegerUnsynchronized cHold;
public ConsumeInteger( HoldIntegerUnsynchronized h )
{
super( "ConsumeInteger" );
cHold = h;
}
The run() method
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 );
System.err.println(
getName() + " retrieved values totaling: " + sum +
"\nTerminating " + getName() );
}
}
Definition of threaded class
ProduceInteger
// Fig. 15.4: ProduceInteger.java
// Definition of threaded class ProduceInteger
public class ProduceInteger extends Thread {
private HoldIntegerUnsynchronized pHold;
public ProduceInteger( HoldIntegerUnsynchronized h )
{
super( "ProduceInteger" );
pHold = h;
}
The run() method again
public void run()
{
for ( int count = 1; count <= 10; count++ ) {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
}
pHold.setSharedInt( count );
}
System.err.println( getName() +
" finished producing values" +
"\nTerminating " + getName() );
}
}
Multiple threads modifying shared
object
// Fig. 15.4: SharedCell.java
// Show multiple threads modifying shared object.
public class SharedCell {
public static void main( String args[] )
{
HoldIntegerUnsynchronized h =
new HoldIntegerUnsynchronized();
ProduceInteger p = new ProduceInteger( h );
ConsumeInteger c = new ConsumeInteger( h );
p.start();
c.start();
}
}
Definition of threaded class
ConsumeInteger
// Fig. 15.5: ConsumeInteger.java
// Definition of threaded class ConsumeInteger
public class ConsumeInteger extends Thread {
private HoldIntegerSynchronized cHold;
public ConsumeInteger( HoldIntegerSynchronized h )
{
super( "ConsumeInteger" );
cHold = h;
}
Another run() method
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 );
System.err.println(
getName() + " retrieved values totaling: " + sum + "\nTerminating " + getName() );
}
}
Definition of class
HoldIntegerSynchronized
// Fig. 15.5: HoldIntegerSynchronized.java
// Definition of class HoldIntegerSynchronized that uses thread synchronization to ensure that both
// threads access sharedInt at the proper times.
public class HoldIntegerSynchronized {
private int sharedInt = -1;
private boolean writeable = true; // condition variable
public synchronized void setSharedInt( int val )
{
while ( !writeable ) { // not the producer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
}
System.err.println( Thread.currentThread().getName() +
" setting sharedInt to " + val );
sharedInt = val;
writeable = false;
notify(); // tell a waiting thread to become ready
}
public synchronized int getSharedInt()
{
while ( writeable ) { // not the consumer's turn
try {
wait();
}
catch ( InterruptedException e ) {
e.printStackTrace();
}
}
writeable = true;
notify(); // tell a waiting thread to become ready
System.err.println( Thread.currentThread().getName() +
" retrieving sharedInt value " + sharedInt );
return sharedInt;
}
}
Definition of threaded class
ProduceInteger
// Fig. 15.5: ProduceInteger.java
// Definition of threaded class ProduceInteger
public class ProduceInteger extends Thread {
private HoldIntegerSynchronized pHold;
public ProduceInteger( HoldIntegerSynchronized h )
{
super( "ProduceInteger" );
pHold = h;
}
public void run()
{
for ( int count = 1; count <= 10; count++ ) {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
public void run()
{
for ( int count = 1; count <= 10; count++ ) {
// sleep for a random interval
try {
Thread.sleep( (int) ( Math.random() * 3000 ) );
}
catch( InterruptedException e ) {
System.err.println( e.toString() );
}
pHold.setSharedInt( count );
}
System.err.println( getName() +
" finished producing values" +
"\nTerminating " + getName() );
}
}
Show multiple threads modifying
shared object
// Fig. 15.5: SharedCell.java
// Show multiple threads modifying shared object.
public class SharedCell {
public static void main( String args[] )
{
HoldIntegerSynchronized h =
new HoldIntegerSynchronized();
ProduceInteger p = new ProduceInteger( h );
ConsumeInteger c = new ConsumeInteger( h );
p.start();
c.start();
}
}
Definition of threaded class
ConsumeInteger
// Fig. 15.6: ConsumeInteger.java
// Definition of threaded class ConsumeInteger
import javax.swing.JTextArea;
public class ConsumeInteger extends Thread {
private HoldIntegerSynchronized cHold;
private JTextArea output;
public ConsumeInteger( HoldIntegerSynchronized h,
JTextArea o )
{
super( "ConsumeInteger" );
cHold = h;
output = o;
}
}
Another run() method
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.append( "\n" + getName() +
" retrieved values totaling: " + sum +
"\nTerminating " + getName() + "\n" );
}
Definition of class
HoldIntegerSynchronized
// Fig. 15.6: HoldIntegerSynchronized.java
// Definition of class HoldIntegerSynchronized that
// uses thread synchronization to ensure that both
// threads access sharedInt at the proper times.
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;
}
}
public void displayBuffer( JTextArea out, int buf[] )
{
DecimalFormat formatNumber = new DecimalFormat( " #;-#" );
output.append( "\tbuffer: " );
for ( int i = 0; i < buf.length; i++ )
out.append( " " + formatNumber.format( buf[ i ] ));
}
}
private JTextArea output;
sharedInt[ writeLoc ] = val;
readable = true;
output.append( "\nProduced " + val + " into cell " + writeLoc );
writeLoc = ( writeLoc + 1 ) % 5;
output.append( "\twrite " + writeLoc + "\tread " + readLoc);
displayBuffer( output, sharedInt );
if ( writeLoc == readLoc ) {
writeable = false;
output.append( "\nBUFFER FULL" );
}
notify();
public synchronized int getSharedInt()
{
int val;
while ( !readable ) {
try {
output.append( " WAITING TO CONSUME" );
wait();
}
catch ( InterruptedException e ) {
System.err.println( e.toString() );
}
}
writeable = true;
val = sharedInt[ readLoc ];
output.append( "\nConsumed " + val + " from
cell " + readLoc );
readLoc = ( readLoc + 1 ) % 5;
output.append( "\twrite " + writeLoc + "\tread "
+ readLoc );
displayBuffer( output, sharedInt );
if ( readLoc == writeLoc ) {
readable = false;
output.append( "\nBUFFER EMPTY" );
}
notify();
return val;
public HoldIntegerSynchronized( JTextArea o )
{
output = o;
}
public synchronized void setSharedInt( int val )
{
while ( !writeable ) {
try {
output.append( " WAITING TO PRODUCE " + val );
wait();
}
catch ( InterruptedException e ) {
System.err.println( e.toString() );
}
}
Definition of threaded class
ProduceInteger
// Fig. 15.6: ProduceInteger.java
// Definition of threaded class ProduceInteger
import javax.swing.JTextArea;
public class ProduceInteger extends Thread {
private HoldIntegerSynchronized pHold;
private JTextArea output;
public ProduceInteger( HoldIntegerSynchronized h,
JTextArea 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.append( "\n" + getName() +
" finished producing values" +
"\nTerminating " + getName() + "\n" );
}
}
Multiple threads modifying shared
object
// Fig. 15.6: SharedCell.java
// Show multiple threads modifying shared object.
import java.text.DecimalFormat;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SharedCell extends JFrame {
public SharedCell()
{
super( "Demonstrating Thread Synchronization" );
JTextArea output = new JTextArea( 20, 30 );
getContentPane().add( new JScrollPane( output ) );
setSize( 500, 500 );
show();
// set up threads and start threads
HoldIntegerSynchronized h =
new HoldIntegerSynchronized( output );
ProduceInteger p = new ProduceInteger( h, output );
ConsumeInteger c = new ConsumeInteger( h, output );
p.start();
c.start();
}
public static void main( String args[] )
{
SharedCell app = new SharedCell();
app.addWindowListener(
new WindowAdapter() {
public void windowClosing( WindowEvent e )
{
System.exit( 0 );
}
}
);
}
}
Demonstrating the
Runnableinterface
// Fig. 15.7: RandomCharacters.java
// Demonstrating the Runnableinterface
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RandomCharacters extends JApplet
implements Runnable,
ActionListener {
private String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private JLabel outputs[];
private JCheckBox checkboxes[];
private final static int SIZE = 3;
private Thread threads[];
private boolean suspended[];
public void init()
{
outputs = new JLabel[ SIZE ];
checkboxes = new JCheckBox[ SIZE ];
threads = new Thread[ SIZE ];
suspended = new boolean[ SIZE ];
Container c = getContentPane();
c.setLayout( new GridLayout( SIZE, 2, 5, 5 ) );
for ( int i = 0; i < SIZE; i++ ) {
outputs[ i ] = new JLabel();
outputs[ i ].setBackground( Color.green );
outputs[ i ].setOpaque( true );
c.add( outputs[ i ] );
checkboxes[ i ] = new JCheckBox( "Suspended" );
checkboxes[ i ].addActionListener( this );
c.add( checkboxes[ i ] );
}
}
public void start()
{
// create threads and start every time start is called
for ( int i = 0; i < threads.length; i++ ) {
threads[ i ] =
new Thread( this, "Thread " + (i + 1) );
threads[ i ].start();
}
}
public void run()
{
Thread currentThread = Thread.currentThread();
int index = getIndex( currentThread );
char displayChar;
while ( threads[ index ] == currentThread ) {
// sleep from 0 to 1 second
try {
Thread.sleep( (int) ( Math.random() * 1000 ) );
synchronized( this ) {
while ( suspended[ index ] &&
threads[ index ] == currentThread )
wait();
}
}
catch ( InterruptedException e ) {
System.err.println( "sleep interrupted" );
}
displayChar = alphabet.charAt(
(int) ( Math.random() * 26 ) );
outputs[ index ].setText( currentThread.getName() + ": " + displayChar );
}
System.err.println(
currentThread.getName() + " terminating" );
}
private int getIndex( Thread current )
{
for ( int i = 0; i < threads.length; i++ )
if ( current == threads[ i ] )
return i;
return -1;
}
public synchronized void stop()
{
// stop threads every time stop is called
// as the user browses another Web page
for ( int i = 0; i < threads.length; i++ )
threads[ i ] = null;
notifyAll();
}
public synchronized void actionPerformed( ActionEvent e )
{
for ( int i = 0; i < checkboxes.length; i++ ) {
if ( e.getSource() == checkboxes[ i ] ) {
suspended[ i ] = !suspended[ i ];
outputs[ i ].setBackground(
!suspended[ i ] ? Color.green : Color.red );
if ( !suspended[ i ] )
notify();
return;
}
}
}
}