Download Ch13

Document related concepts
no text concepts found
Transcript
presentation slides for
Object-Oriented Problem Solving
JAVA, JAVA, JAVA
Second Edition
Ralph Morelli
Trinity College
Hartford, CT
published by Prentice Hall
Java, Java, Java
Object Oriented Problem Solving
Chapter 13: Threads and
Concurrent Programming
Objectives
• Understand the concept of a thread.
• Know how to design and write
multithreaded programs.
• Be able to use the Thread class and the
Runnable interface.
• Understand the life-cycle of a thread.
• Know how to synchronize threads.
• Appreciate the use of inheritance in
threaded applications.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Outline
• What Is a Thread?
• From the Java Library: The Thread class
• Using Threads to Improve Interface
Responsiveness
• Thread States and Life Cycle
• Case Study: Cooperating Threads
• Case Study: The Spider and Fly Threads
• Object-Oriented Design: Inheritance and
Polymorphism
• In the Laboratory: The Spider, Fly, and Bee
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
What Is a Thread?
• A thread (or thread of control) is a sequence
of executable statements within a program.
• Java Application: starts at main() and
executes statements in sequence.
• The Java Virtual Machine in multi-threaded
-- it has more than one thread executing.
• Garbage collector thread -- a JVM thread to
collect memory of discarded objects.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Concurrent Execution of Threads
• Multitasking is the technique of concurrently
executing several tasks within a program.
• On a sequential computer the threads share
the single CPU (Central Processing Unit).
• Time slicing -- each thread alternatively gets
a slice (quantum) of the CPU's time.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Multithreaded Numbers
• Create several NumberThreads and have
each thread print its ID number 10 times.
NumberThread
overrides the
inherited run()
method..
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The NumberThread Class
• A NumberThread prints its ID 10 times.
public class NumberThread extends Thread {
int num;
public NumberThread(int n) {
num = n;
}
public void run() {
for (int k=0; k < 10; k++) {
System.out.print(num);
} //for
} // run()
} // NumberThread
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
When a thread is
started, it executes
its run() method.
Chapter 13: Threads
The Numbers Class
Creates
NumberThreads
and starts
each one..
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Starting Multiple Threads
• Create 5 NumberThreads and start each one.
public class Numbers {
public static void main(String args[]) {
NumberThread number1, number2, number3, number4, number5;
number1 = new NumberThread(1); number1.start();
number2 = new NumberThread(2); number2.start();
number3 = new NumberThread(3); number3.start();
number4 = new NumberThread(4); number4.start();
number5 = new NumberThread(5); number5.start();
} // main()
} // Numbers
Output: The threads run in the
order they were started.
11111111112222222222333333333344444444445555555555
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Starting Multiple Threads
• The order and timing of threads is
unpredictable.
111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111112222222
222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222223333333333333333333333333
333333333333333333333333333333333333333333333333333333333333333333333
333333333333333333333333333444444444444444444444444444444444444444444
444444444444444444444444444444444444444444444444444444444444444444444
444444444455555555555555555555555555555555555555555555555555555555555
555555555555555555555555555555555555555555555555555555555555552222222
222233333333333333333333333333333333333333333333333333333333333333333
333333333333334444444444444444444444444444445555555555555555555555555
555555555555555555555555555555555555555555555555555555444444444444444
4444444444444444444444444444444444
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The java.lang.Thread Class
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Runnable Interface
• Any object that implements the Runnable
interface can be run as a separate thread.
A Runnable
object
implements
run().
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
A Thread is a Runnable Object
• A Thread can be passed a Runnable
class NumberPrinter implements
object. public
Runnable {
int num;
public NumberPrinter(int n) {
num = n;
}
public void run() {
for (int k=0; k < 10; k++)
System.out.print(num);
} // run()
} // NumberPrinter
Thread number1;
number1 = new Thread(new NumberPrinter(1));
number1.start();
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
A Runnable
object
implements
run().
Create a
Runnable object.
Chapter 13: Threads
Thread Control
• setPriority(int) sets a thread’s priority to an value
between Thread.MIN_PRIORITY and
Thread.MAX_PRIORITY.
public NumberThread(int n) {
num = n;
setPriority(n);
}
for (int k = 0; k < 2000000;
k++)
if (k % 1000000 == 0)
System.out.print(num);
Set NumberThread’s
priority to its ID number.
Run 2 million iterations,
printing on every million.
5544332211
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Threads run in
priority order.
Chapter 13: Threads
Design Issues
• The Runnable interface lets you turn an
existing class into a thread.
• A higher priority thread will preempt threads
of lower priority.
• Thread implementation is platform
dependent.
• A high-priority thread that never gives up the
CPU can starve lower-priority threads.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Forcing Threads to Sleep
• The sleep() method causes the thread to yield
for a fixed amount of real time.
• For example, a revised NumberPrinter.run()
public void run() {
for (int k=0; k < 10; k++) {
try {
Thread.sleep((long)(Math.random() * 1000));
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
System.out.print(num);
} // for
} // run()
Sleep up to
1000
milliseconds.
Threads run in
random order.
14522314532143154232152423541243235415523113435451
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Thread States and Life Cycle
• Thread life cycle consists of several states.
State Description
Ready
Running
Waiting
Sleeping
Blocked
Dead
Ready to run and
waiting for the CPU.
Executing on the CPU.
Waiting for some
event to happen.
Sleeping for a time.
Waiting for I/O to
finish.
Terminated
Key: Regular font-- System control
method() -- program control
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Asynchronous Nature of Threads
• Threads are asynchronous -- their timing
and order of execution is unpredictable.
• It is not possible to determine when a thread
thread might be preempted.
Several Machine Instructions
Single Java Statement
int N = 5 + 3;
(1) Fetch 5 from memory and store it
in register A.
(2) Add 3 to register A.
(3) Assign the value in register A
to N.
Where preemptions
could occur.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Case Study: Improving Responsiveness
• A multithreaded program can be executing
in a loop and still respond to user input.
• Test User Response:
Stop the program from
drawing random dots as
soon as the first red dot
appears. Report the
number of red dots.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design: Problem Decomposition
• RandomDotApplet -- handles the GUI.
• Dotty -- draws the N dots
Uses
Constructor supplies N
and reference to JPanel.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design: RandomDot Applet
• Problem Decomposition
– RandomDotApplet -- manages GUI.
– Dotty -- contains draw() and clear()
• Initial Definition RandomDotApplet
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
// Import Swing classes
Dotty handles
the drawing.
public class RandomDotApplet extends JApplet implements ActionListener{
public final int NDOTS = 10000;
private Dotty dotty;
// The drawing class
private JPanel controls = new JPanel();
private JPanel canvas = new JPanel();
private JButton draw = new JButton("Draw");
private JButton clear = new JButton("Clear");
} // RandomDotApplet
GUI elements.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
GUI Design: RandomDotApplet
• GUI:
public void init() {
getContentPane().setLayout(new BorderLayout());
draw.addActionListener(this);
clear.addActionListener(this);
controls.add(draw);
controls.add(clear);
canvas.setBorder(BorderFactory.createTitledBorder("Drawing Canvas"));
getContentPane().add("North", controls);
getContentPane().add("Center", canvas);
getContentPane().setSize(400, 400);
} // init()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design: Dotty Class
• A Dotty object draws N dots on a JPanel.
import java.awt.*;
import javax.swing.*;
// Import Swing classes
Unthreaded Dotty.
public class Dotty {
private static final int HREF = 20, VREF = 20, LEN = 200;
private JPanel canvas;
private int nDots;
// Number of dots to draw
private int nDrawn;
// Number of dots drawn
private int firstRed = 0; // Number of the first red dot
public Dotty(JPanel canv, int dots) {
canvas = canv;
nDots = dots;
}
} // Dotty
Constructor supplies N
and reference to JPanel.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Dotty Methods: draw() and clear()
public void draw() {
Graphics g = canvas.getGraphics();
for (nDrawn = 0; nDrawn < nDots; nDrawn++) {
int x = HREF + (int)(Math.random() * LEN);
int y = VREF + (int)(Math.random() * LEN);
g.fillOval(x, y, 3, 3);
// Draw a dot
if ((Math.random() < 0.001) && (firstRed == 0)) {
g.setColor(Color.red);
// Change color to red
firstRed = nDrawn;
}
} //for
} // draw()
Draw N dots.
At some random point,
switch color to red.
public void clear() {
// Clear screen and report result
Graphics g = canvas.getGraphics();
g.setColor(canvas.getBackground());
g.fillRect(HREF, VREF, LEN + 3, LEN + 3);
System.out.println("Number of red dots = " + (nDrawn-firstRed));
} // clear()
Report results.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: Single-threaded Control
• Applet and Dotty are part of same thread.
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == draw) {
dotty = new Dotty(canvas, NDOTS);
dotty.draw();
} else {
dotty.clear();
}
} // actionPerformed()
Poor Response Time: The
applet’s clear() must wait until
dotty’s draw() loop ends.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Multithreaded Design
• Applet and Dotty are separate threads.
Dotty will run as a separate
thread from the applet.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: A Runnable Dotty
• If a thread sleeps, waiting threads can run.
public class Dotty implements Runnable {
private static final int HREF = 20, VREF = 20, LEN = 200;
private JPanel canvas;
private int nDots;
// Number of dots to draw
private int nDrawn;
// Number of dots drawn
private int firstRed = 0;
// Number of the first red dot
private boolean isCleared = false; // The panel is cleared
Make Dotty Runnable.
public void run() {
draw();
}
public Dotty(JPanel canv, int dots) {
canvas = canv;
nDots = dots;
}
} // Dotty
isCleared controls
draw() loop
run() just calls draw()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Modified draw() and clear()
public void draw() {
Graphics g = canvas.getGraphics();
for (nDrawn = 0; !isCleared && nDrawn < nDots; nDrawn++) {
int x = HREF + (int)(Math.random() * LEN);
int y = VREF + (int)(Math.random() * LEN);
g.fillOval(x, y, 3, 3);
// Draw a dot
if (Math.random() < 0.001 && firstRed == 0) {
g.setColor(Color.red);
// Change color to red
firstRed = nDrawn;
}
try {
Thread.sleep(1) ;
// Sleep for an instant
} catch (InterruptedException e) {
System.out.println(e.getMessage());
} //try
} //for
} // draw()
Stop if panel is cleared.
Sleep after
each dot.
public void clear() {
// Clear screen and report result
isCleared = true;
Graphics g = canvas.getGraphics();
draw()
g.setColor(canvas.getBackground());
g.fillRect(HREF, VREF, LEN + 3, LEN + 3);
System.out.println("Number of red dots = " + (nDrawn-firstRed));
} // clear()
Stop the
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
loop.
Implementation: Multithreaded Control
• If Dotty sleeps, the applet thread can run.
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == draw) {
dotty = new Dotty( canvas, NDOTS );
dottyThread = new Thread(dotty);
dottyThread.start();
} else {
dotty.clear();
}
} // actionPerformed()
Create a Dotty thread and
start it drawing.
Good Response Time: Because
Dotty sleeps after every dot,
clear() will run immediately.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design Issues
• Effective Design: Use a separate thread for
an interactive interface.
• Tradeoff: Dotty draws a little slower but the
interface is more responsive.
• Algorithm: The correct way to stop a thread
is to make its run() method dependent on a
variable (e.g., isCleared).
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Case Study: Cooperating Threads
• Cooperating threads require explicit
synchronization and coordination.
• Problem: Simulate a bakery waiting line
with a clerk and one or more customers. Use
a take-a-number device to manage waiting.
• Class Decomposition:
– Bakery: main program, starts the threads.
– TakeANumber: keeps track of who’s next.
– Clerk: serves the next customer
– Customer: waits on line.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Multithreaded Bakery Simulation
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
TakeANumber Class (Version 1)
• Shared Resource: A TakeANumber object is
shared by several threads.
class TakeANumber {
private int next = 0;
private int serving = 0;
// Next place in line
// Next customer to serve
public synchronized int nextNumber() {
next = next + 1;
return next;
} // nextNumber()
public int nextCustomer() {
++serving;
return serving;
} // nextCustomer()
} // TakeANumber
Java, Java, Java, 2E by R. Morelli
Used by customers.
Used by clerk.
A synchronized
method cannot be
preempted.
Copyright 2002. All rights reserved.
Chapter 13: Threads
Java Monitors and Mutual Exclusion
• Monitor: a mechanism than ensures only one thread
at a time can execute a synchronized method.
• When a synchronized method -- nextNumber() -is called, its object -- TakeANumber -- is locked.
• Mutual exclusion: While an object is locked, none
of its synchronized methods can be run.
• While one customer is getting a number, it can’t be
preempted by another customer.
• Effective Design: Synchronization. To provide
mutually exclusive access to an object’s methods,
declare them synchronized.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design: The Customer Class
• Customers take the next number.
Class variable.
Unique ID.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: The Customer Class
• Customers take the next number.
Class variable.
public class Customer extends Thread {
private static int number = 10000;
// Initial ID number
private int id;
private TakeANumber takeANumber;
public Customer( TakeANumber gadget ) {
id = ++number;
takeANumber = gadget;
}
public void run() {
try {
sleep( (int)(Math.random() * 1000 ) );
System.out.println("Customer " + id + " takes ticket " +
takeANumber.nextNumber());
} catch (InterruptedException e) {
System.out.println("Exception " + e.getMessage());
}
} // run()
} // Customer
Unique ID.
This customer may
have to wait.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Design: The Clerk Class
• Clerks repeatedly serve the next customer.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: The Clerk Class
• Clerks repeatedly serve the next customer.
public class Clerk extends Thread {
private TakeANumber takeANumber;
public Clerk(TakeANumber gadget) {
takeANumber = gadget;
}
public void run() {
while (true) {
try {
sleep( (int)(Math.random() * 50));
System.out.println("Clerk serving ticket " +
takeANumber.nextCustomer());
} catch (InterruptedException e) {
System.out.println("Exception " + e.getMessage()
);
}
} //while
} //run()
} // Clerk
Infinite loop.
Serve next
customer.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Bakery Class
• Bakery starts clerk and customer threads,
passing each a reference to TakeANumber.
public class Bakery {
public static void main(String args[]) {
System.out.println( "Starting clerk and customer threads"
);
TakeANumber numberGadget = new TakeANumber();
Clerk clerk = new Clerk(numberGadget);
clerk.start();
for (int k = 0; k < 5; k++) {
Customer customer = new Customer(numberGadget);
customer.start();
}
} // main()
} // Bakery
1 clerk
5 customers
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Problem: Nonexistent Customers
• Problem: Clerk doesn’t wait for customers.
Starting clerk and customer
threads
Clerk serving ticket 1
Clerk serving ticket 2
Clerk serving ticket 3
Clerk serving ticket 4
Clerk serving ticket 5
Customer 10004 takes ticket
Customer 10002 takes ticket
Clerk serving ticket 6
Customer 10005 takes ticket
Clerk serving ticket 7
Clerk serving ticket 8
Clerk serving ticket 9
Clerk serving ticket 10
Customer 10001 takes ticket
Customer 10003 takes ticket
Java, Java, Java, 2E by R. Morelli
Clerk thread should wait until
a customer takes a number.
1
2
3
4
5
Copyright 2002. All rights reserved.
Chapter 13: Threads
Redesign: Check for Customers
Clerk should check if
customers are waiting.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Synchronize: Clerk Waits for Customers
• Solution: Modify Clerk.run() ...
public void run() {
while (true) {
try {
sleep((int)(Math.random() * 50));
if (takeANumber.customerWaiting())
System.out.println("Clerk serving ticket
" +
takeANumber.nextCustomer());
} catch (InterruptedException e) {
System.out.println("Exception " +
e.getMessage() );
}
} // while
} // run()
Clerk checks for customer.
… And TakeANumber:
Java, Java, Java, 2E by R. Morelli
public boolean customerWaiting()
{
return next > serving;
}
Copyright 2002. All rights reserved.
Chapter 13: Threads
Thread Cooperation
• Effective Design: Thread cooperation must
be designed into the algorithm.
Starting clerk and customer threads
Customer 10003 takes ticket 1
Clerk serving ticket 1
Customer 10005 takes ticket 2
Clerk serving ticket 2
Customer 10001 takes ticket 3
Clerk serving ticket 3
Customer 10004 takes ticket 4
Clerk serving ticket 4
Customer 10002 takes ticket 5
Clerk serving ticket 5
Java, Java, Java, 2E by R. Morelli
Service follows
customer’s arrival.
Copyright 2002. All rights reserved.
Chapter 13: Threads
Problem: Critical Sections
• A critical section is a section of a thread that
should not be preempted in the middle.
• If we simulate the preemption of:
System.out.println("Customer " + id + " takes ticket " +
takeANumber.nextNumber());
What if another
thread runs here?
public void run() { // Customer.run()
try {
int myturn = takeANumber.nextNumber();
sleep( (int)(Math.random() * 1000 ) );
System.out.println("Customer " + id + " takes ticket " + myturn);
} catch (InterruptedException e) {
System.out.println("Exception " + e.getMessage());
}
} // run()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Problem: Misleading Output
• If there’s a break (preemption) between a
customer’s taking a number and reporting its
number, we could get:
Starting clerk and customer threads
Clerk serving ticket 1
Clerk serving ticket 2
Clerk serving ticket 3
Customer 10004 takes ticket 4
Clerk serving ticket 4
Clerk serving ticket 5
Customer 10001 takes ticket 1
Customer 10002 takes ticket 2
Customer 10003 takes ticket 3
Customer 10005 takes ticket 5
Java, Java, Java, 2E by R. Morelli
Logically, our code insures
that the clerk can’t serve
until a ticket is taken but ...
… this output does not
reflect the true state of
the simulation.
Copyright 2002. All rights reserved.
Chapter 13: Threads
Creating a Critical Section
• Let TakeANumber report the state.
public class TakeANumber {
private int next = 0;
private int serving = 0;
Critical Sections:
Synchronized methods
cannot be preempted.
// Next place in line
// Next customer to serve
public synchronized int nextNumber(int custId) {
next = next + 1;
System.out.println( "Customer " + custId + " takes ticket " + next );
return next;
}
public synchronized int nextCustomer() {
++serving;
System.out.println(" Clerk serving ticket " + serving );
return serving;
}
public synchronized boolean customerWaiting() {
return next > serving;
}
} // TakeANumber
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Revised Customer and Clerk
• The clerk and customers do no reporting.
public void run() { // Customer.run()
Just take a
try {
sleep((int)(Math.random() * 2000));
number.
takeANumber.nextNumber(id);
} catch (InterruptedException e) {
System.out.println("Exception: " +
Just serve a
e.getMessage() );
}
customer.
} // run() public void run() {
// Clerk.run()
for (int k = 0; k < 10; k++) {
try {
sleep( (int)(Math.random() * 1000));
if (takeANumber.customerWaiting())
takeANumber.nextCustomer();
} catch (InterruptedException e) {
System.out.println("Exception: " +
e.getMessage());
}
} // for
} // run()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Thread Coordination Principle
• Correct output:
Customers served in the
correct order no matter
how they arrive.
Starting clerk and customer
threads
Customer 10001 takes ticket
Clerk serving ticket 1
Customer 10003 takes ticket
Customer 10002 takes ticket
Clerk serving ticket 2
Customer 10005 takes ticket
Customer 10004 takes ticket
Clerk serving ticket 3
Clerk serving ticket 4
Clerk serving ticket 5
1
2
3
4
5
• Effective Design: Use critical sections to
enforce mutual exclusion and to coordinate
threads.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Busy Waiting Problem
• Even though its threads are properly
coordinated, our bakery simulation uses busy
waiting in the Clerk class:
public void run() {
for (int k = 0; k < 10; k++) {
try {
sleep( (int)(Math.random() * 1000));
if (takeANumber.customerWaiting())
takeANumber.nextCustomer();
} catch (InterruptedException e) {
System.out.println("Exception: " +
e.getMessage());
}
} // for
} // run()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Busy waiting.
Wait in a loop.
Chapter 13: Threads
Using wait/notify to Coordinate Threads
• The wait() method puts a thread into a
waiting state, and notify() takes a thread out
of waiting and places it in the ready queue.
• Alternative Design: The clerk waits to be
notified by a customer.
• This requires modifications to
TakeANumber and Clerk classes.
• Producer/Consumer Model: two threads
share a resource, one serving to produce it
and the other to consume it.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Final TakeANumber Design
These methods use
wait() and notify()
to coordinate clerk
and customers.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Revised TakeANumber Class
The clerk must wait for
public synchronized int nextCustomer() {
try {
a customer to arrive.
while (next <= serving) {
System.out.println(" Clerk waiting ");
wait();
}
} catch(InterruptedException e) {
System.out.println("Exception " + e.getMessage() );
} finally {
++serving;
System.out.println(" Clerk serving ticket " + serving );
return serving;
}
} // nextCustomer()
A customer must
notify the clerk that
is has arrived.
public synchronized int nextNumber(int custId) {
next = next + 1;
System.out.println( "Customer " + custId +
" takes ticket " + next );
notify();
return next;
} // nextNumber()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Revised Clerk Class
• The Clerk.run() method is now simplified to:
public void run() {
while (true) {
Infinite loop.
try {
sleep((int)(Math.random() * 1000));
takeANumber.nextCustomer();
} catch (InterruptedException e) {
System.out.println("Exception: " + e.getMessage() );
}
} // while
Starting clerk and customer
} // run()
threads
Customer 10004 takes ticket 1
Customer 10002 takes ticket 2
Clerk serving ticket 1
New Output
Clerk serving ticket 2
Customer 10005 takes ticket 3
Customer 10003 takes ticket 4
Clerk serving ticket 3
Customer 10001 takes ticket 5
Clerk will be notified when a
Clerk serving ticket 4
Clerk serving ticket 5
new customer arrives.
Clerk waiting
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Restrictions on wait/notify Mechanism
• Both wait() and notify() are methods of the Object
class. This enables them to lock objects.
• A wait() method can be used within any
synchronized method, not just within a Thread.
• Both wait() and notify() must be used within
synchronized methods. Otherwise you will cause a
IllegalMonitorStateException with the message
“current thread not owner.”
• When wait() is used within a synchronized method,
the lock on that object is released, allowing other
methods to call the object’s synchronized methods.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Case Study: The Spider and Fly Threads
• Problem: Simulate
2 independent
CyberPets, a Fly
that buzzes around
and a Spider that
dreams about
catching it.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Spider/Fly: Decomposition
• Three objects, three
separate threads:
– Applet: implements
the interface.
– Spider: our familiar
CyberPet
– Fly: a buzzing fly
Communication
Model
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Spider/Fly: Class Hierarchy
• Multiple Inheritance: Spider and Fly inherit
CyberPet characteristics and Thread
characteristics.
public class Fly extends CyberPet implements Runnable { ... }
public class Spider extends CyberPet implements Runnable { ... }
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Revised CyberPet Class
To be inherited, state and
name cannot be private
A new dream state
and method()
Both Spider and Fly
use the delay() method.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: CyberPet Class
public class CyberPet {
protected int state;
protected String name;
public static final int
public static final int
public static final int
public static final int
public static final int
public static final int
Class Constants
DEAD = -1;
EATING = 0;
SLEEPING = 1;
THINKING = 2;
DREAMING = 3;
FLYING = 4;
The new dream()
method
// For flying cyberpets
public void dream() {
state = DREAMING;
}
protected void delay(int N) { // delay for N milliseconds
try {
Thread.sleep(N);
} catch (InterruptedException e) {
System.out.println(e.toString());
}
} // delay()
} // CyberPet
Forces the thread that
calls it to sleep for N
milliseconds..
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Fly Class
Constants
constrain fly’s
location and
motion.
Note reference to applet.
The Fly buzzes until it dies.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Implementation: Fly Class
Constants.
import java.awt.*;
public class Fly extends CyberPet implements Runnable {
private static final int XMIN = 225;
// Flying region
private static final int XMAX = 300;
private static final int YMIN = 245;
private static final int YMAX = 305;
private static final int SIDE = 5;
// Size of fly
private static final int MAX_RANGE = 15; // Fly’s motion
private static final int MIN_DELTA = -10;
private CyberPetApplet applet;
// Reference to interface
private Point location;
// The fly's coordinates
Note reference to applet.
public Fly (CyberPetApplet app) {
applet = app;
location = new Point(XMAX, YMAX); // Starting Location
state = FLYING;
}
public void run() {
while (state != DEAD) {
buzzaround();
delay(125);
} //while
} // run()
} // Fly
Java, Java, Java, 2E by R. Morelli
The Fly buzzes until it dies.
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Fly.buzzaround() Method
Erase
public synchronized void buzzaround() {
state = FLYING;
Graphics g = applet.getGraphics();
g.setColor(Color.white);
// Erase current image
g.fillRect(location.x, location.y, SIDE, SIDE);
// Calculate new location
int dx = (int)(MIN_DELTA + Math.random() * MAX_RANGE);
int dy = (int)(MIN_DELTA + Math.random() * MAX_RANGE);
if (location.x + dx >= XMIN) location.x = location.x + dx;
else location.x = XMIN;
if (location.y + dy >= YMIN) location.y = location.y + dy;
else location.y = YMIN;
if (location.x + dx <= XMAX) location.x = location.x + dx;
else
location.x = XMAX;
if (location.y + dy <= YMAX) location.y = location.y + dy;
else location.y = YMAX;
Move
within
bounds
// Draw new image at new location
g.setColor(Color.red);
g.fillRect(location.x, location.y, SIDE, SIDE);
} // buzzaround()
Redraw
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Thread Communication
• To simulate the Spider eating the Fly, the
Spider will need to know the Fly’s location.
public Point getLocation() {
return location;
}
//Fly.getLocation()
• The Fly should die when eaten.
public synchronized void die() {
state = DEAD;
}
Java, Java, Java, 2E by R. Morelli
// Fly.die()
Causes the run() loop
to terminate.
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Spider Class
• The Spider behaves as before, except now it
can also dream.
Note that it overrides
eat(), sleep(), think()
and dream().
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Spider.run() Method
• The Spider’s behavior contains randomness.
Spider’s behavior is
autonomous and random.
public void run() {
while (true) {
int choice = (int)(Math.random() * 4);
if (choice == 0)
autoeat();
else if (choice == 1)
autosleep();
else if (choice == 2)
private void autoeat() {
think();
Graphics g = applet.getGraphics();
else
state = EATING;
dream();
applet.updateStateField();
delay(5000);
for (int k = 0; k < SLEEPING_IMG; k++)
} //while
{
} // run()
g.drawImage(image[k], 20, 100,
applet);
delay(200) ;
}
} // autoeat()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Spider.eat() Method
• The Spider can still be commanded to eat but
it doesn’t always obey.
Spider disobeys
1/3 of the time.
public void eat() {
Graphics g = applet.getGraphics();
int choice = (int) ( Math.random() * 3 );
if ( choice == 2 )
// i.e., 1 in 3 chance
g.drawImage(image[NOT_HUNGRY_IMG], 20, 100, applet);
else {
state = EATING;
for (int k = 0; k < SLEEPING_IMG; k++) {
g.drawImage(image[k], 20, 100, applet);
delay(200) ;
}
} // else
} // eat()
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The Spider.dream() Method
• The Spider dreams it is a frog.
public synchronized void dream() {
state = DREAMING;
applet.updateStateField();
Graphics g = applet.getGraphics();
// Draw dreaming image
g.drawImage(image[DREAMING_IMG], 20, 100, applet);
delay(5000);
g.drawImage(image[FROG], 20, 100, applet); // Transform to a frog
delay(5000);
flyLocation = applet.getFlyLocation();
// Look at the fly
g.setColor( Color.pink);
g.drawLine(FROG_X, FROG_Y, flyLocation.x, flyLocation.y); // Eat the
g.drawLine(FROG_X + 1, FROG_Y + 1, flyLocation.x + 1, flyLocation.y +
g.drawLine(FROG_X + 2, FROG_Y + 2, flyLocation.x + 1, flyLocation.y +
g.drawLine(FROG_X + 3, FROG_Y + 3, flyLocation.x + 1, flyLocation.y +
applet.eatFly();
delay(250);
g.drawImage(image[HAPPY_FROG], 20, 100, applet);
delay(5000);
applet.newFly();
} // dream()
Spider becomes a frog...
...and eats the fly.
fly
1);
1);
1);
The applet serves
as a go-between.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
The CyberPetApplet Class
• The applet creates the Spider and the Fly.
private Spider spidey = new Spider ("Spidey", this);
private Fly pest = new Fly(this);
// Create a Pet
// and a Fly
• It starts their threads in init().
new Thread(spidey).start();
new Thread(pest).start();
// Start spidey thread (in init())
// Start the fly thread (in init())
• It mediates their interaction.
public void eatFly() {
pest.die();
}
public Point getFlyLocation() {
return pest.getLocation();
}
Java, Java, Java, 2E by R. Morelli
Called by Spider.
public void newFly() {
pest = new Fly(this);
new Thread(pest).start();
}
Copyright 2002. All rights reserved.
Chapter 13: Threads
OOD: Inheritance and Polymorphism
• Inheritance: Spider and Fly both inherit
characteristics of CyberPet and both have
Thread characteristics via Runnable
interface
• Shared methods defined in CyberPet.
• Polymorphism: run() behaves differently in
each Thread subclass.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
In the Laboratory: The Spider, Fly, and Bee
The objectives of this lab are:
• To define a Bee subclass of CyberPet.
• To incorporate a Bee instance into the
spider/fly animation.
• To understand appropriate uses of
inheritance in object-oriented design.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Lab: Problem Statement
• Define a Bee subclass of CyberPet such that:
– Bees are magenta, whereas Flys are red.
– Bees are bigger than Flys.
– New Bees start from a different location
than Flys.
– Bees make a beep-beep sound when they
die.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Object Oriented Design
FlyingInsect is
abstract because
lastGasp() is
abstract.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Lab: The FlyingInsect Class
• Instance Variables: color, size, location.
• Constructor Signature:
FlyingInsect (CyberPetApplet app, Color col, int
siz, Point loc);
• Adapt getLocation() and run() from Fly.
• Generalize buzzaround() and die()
• Polymorphic abstract method: lastGasp()
– Called in die().
– Gives the insect’s last sound.
– Implemented in Fly and Bee subclasses.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Lab: The Revised Fly Class
• The revised Fly class contains its constructor
and its version of lastGasp().
• Methods like die(), getLocation(), run() and
buzzaround() are in FlyingInsect.
import java.awt.*;
// Import the GUI components
public class Fly extends FlyingInsect implements Runnable{
public Fly ( CyberPetApplet app ) {
super(app);
}
public void lastGasp(){
Toolkit.getDefaultToolkit().beep();
}
} // Fly
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Lab: The Revised CyberPetApplet
• Necessary Modifications:
– getFlyLocation() should randomly pick
the bee or fly’s location and must
remember which one it picked:
currentPest = (Bee) bee;
– eatFly() must eat the currentPest
– newFly() makes a new Bee or Fly
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Technical Terms
•
•
•
•
•
•
•
•
•
•
•
asynchronous
blocked
busy waiting
concurrent
critical section
dispatched
fetch-execute cycle
lock
monitor
multitasking
multithreaded
Java, Java, Java, 2E by R. Morelli
• mutual exclusion
• priority scheduling
• producer/consumer
model
• quantum
• queue
• ready queue
• round-robin scheduling
• thread
• thread life cycle
• time slicing
Copyright 2002. All rights reserved.
Chapter 13: Threads
Summary Of Important Points
• Multitasking is the technique of executing
several tasks at the same time within a
single program.
• Time slicing allows several threads to share
a single CPU over a given time period.
• A thread can be a subclass of Thread or a
class that implements Runnable. It must
implement the run() method.
• The sleep() method removes a thread from
the CPU for a determinate time, giving
other threads a chance to run.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads
Summary Of Important Points (cont)
• The setPriority() method sets a thread’s
priority.
• Threads are asynchronous. Their timing and
duration is unpredictable.
Java, Java, Java, 2E by R. Morelli
Copyright 2002. All rights reserved.
Chapter 13: Threads