Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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