Download Java threads

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
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;
}
}
}
}
Related documents