1 / 40

Christine M. Mitchell Center for Human-Machine Systems Research (chmsr)

ISYE 7210--Simulation of Real-Time Systems Fall 2005 Threads, Runnable, Interfaces 7210 Class Web site: www.chmsr.gatech.edu/ISyE7210/ Horstmann & Cornel (7 th ed) Code Download Web site: www.horstmann.com/corejava.html. Christine M. Mitchell Center for Human-Machine Systems Research (chmsr)

emcdonough
Download Presentation

Christine M. Mitchell Center for Human-Machine Systems Research (chmsr)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ISYE 7210--Simulation of Real-Time Systems Fall 2005Threads, Runnable, Interfaces7210 Class Web site: www.chmsr.gatech.edu/ISyE7210/Horstmann & Cornel (7th ed) Code Download Web site:www.horstmann.com/corejava.html Christine M. Mitchell Center for Human-Machine Systems Research (chmsr) School of Industrial and Systems Engineering (chmsr lab) ISyE Main, Room 426, 404 385-0363 (office) ISyE Groseclose, Room 334, 404 894-4321 {cm}@chmsr.gatech.edu

  2. Examples of Thread Use Bounce Program (1): Bounce Class • Bounce: Selfish thread example • Classes in Bounce program • Bounce • BounceFrame extends JFrame • BallPanel extends JPanel • Ball • Control program: BounceFrame

  3. Examples of Thread Use Bounce Program (1): Bounce Class import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.util.*; import javax.swing.*; public class Bounce { public static void main(String[] args) { JFrame frame = new BounceFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }//end Bounce class

  4. Examples of Thread Use Bounce Program (1): BounceFrame Class public BounceFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); setTitle("Bounce"); panel = new BallPanel(); add(panel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(); addButton( buttonPanel, "Start", new ActionListener() { public void actionPerformed(ActionEvent event) { addBall(); } }); • Constructs JFame, title, “Bounce” • Constructspanel, BallPanel • Addspanel to (JF)ame • ConstructsbuttonPanel, JPanel • Calls addButton( ) to create “Start”, JButton, which calls addBall( ) public class BounceFrame extends JFrame { private BallPanel panel; public static final int DEFAULT_WIDTH = 450; public static final int DEFAULT_HEIGHT = 350; public static final int STEPS = 1000; public static final int DELAY = 3;

  5. Examples of Thread Use Bounce Program (1): BounceFrame Class public void addButton (Container c, String title, ActionListener listener) { JButton button = new JButton(title); c.add(button); button.addActionListener(listener); } public void addBall() { try { Ball ball = new Ball(); panel.add(ball); for (int i = 1; i <= STEPS; i++) { ball.move(panel.getBounds()); panel.paint(panel.getGraphics()); Thread.sleep(DELAY); } } catch (InterruptedException e){ } } • addButton( )creates a “Close” button, JButton • Close button action: exit program • Adds new button to Container • addBall(…)creates a ball, adds it to panel, & executes loop ball movement //imports addButton(buttonPanel, "Close", new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } });

  6. Examples of Thread Use (1): BallPanel Class //imports public class BallPanel extends JPanel { private ArrayList<Ball> balls = new ArrayList<Ball>(); public void add(Ball b) { balls.add(b); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; for (Ball b : balls) { g2.fill(b.getShape()); } } //end paintComponent } /end BallPanel • Creates a ballPanel instance of JPanel • Creates an ArrayLists of balls • add(…) adds aBall to balls

  7. Examples of Thread Use Bounce Program (1): Ball Class if (x + XSIZE >= bounds.getMaxX()) { x = bounds.getMaxX() - XSIZE; dx = -dx; } if (y < bounds.getMinY()) { y = bounds.getMinY(); dy = -dy; } if (y + YSIZE >= bounds.getMaxY()) { y = bounds.getMaxY() - YSIZE; dy = -dy; } } public Ellipse2D getShape() { return new Ellipse2D.Double(x, y, XSIZE, YSIZE); } } //end Ball class • Moves ball if an edge is reached //imports public class Ball { private static final int XSIZE = 15; private static final int YSIZE = 15; private double x = 0; private double y = 0; private double dx = 1; private double dy = 1; public void move(Rectangle2D bounds) { x += dx; y += dy; if (x < bounds.getMinX()) { x = bounds.getMinX(); dx = -dx; }

  8. Examples of Thread Use BounceProgram (1): BounceFrame class public class BounceFrame extendsJFrame …. public void addBall() { try { Ball ball = new Ball(); panel.add(ball); for (int i = 1; i <= STEPS; i++) { ball.move(panel.getBounds()); panel.paint(panel.getGraphics()); Thread.sleep(DELAY); } //end for: moves ball } //end try • BounceFrame: addBall( ) • Consumes all resources • Executes a for loop 1000 times • Calls Thread.sleep(5000); • Cannot interrupt for 5 ms • Program can not “hear” while loop executes STEP times

  9. Examples of Thread Use BounceThread Program (2): BounceThread Class • Multi-thread example • User-controlled resources • Start: BounceThread:main(…) • Classes • BounceThread • BounceFrame extends JFrame • BallRunnable • BallPanel extends JPanel • Ball

  10. Examples of Thread Use BounceThread Program (2): BounceThread Class • Two threads: threads handle • Bouncing balls • Interface events //BounceThread.java import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.util.*; import javax.swing.*; /** Shows an animated bouncing ball. */ public class BounceThread { public static void main(String[] args) { JFrame frame = new BounceFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); }}

  11. Examples of Thread Use BounceThread Program (2): BounceFrame Class panel = new BallPanel(); add(panel, BorderLayout.CENTER); JPanel buttonPanel = new JPanel(); addButton(buttonPanel, "Start", new ActionListener() { public void actionPerformed(ActionEvent event) { addBall();} }); //end addButton( ) for start button addButton(buttonPanel, "Close", new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } }); add(buttonPanel, BorderLayout.SOUTH); }); //end addButton( ) for close button • Creates graphical thread: Bouncing ball • Creates • Instance of JFrame • panel, BallPanel • Buttons for “Start” & “Close” //imports public class BounceFrame extendsJFrame { private BallPanel panel; public static final int DEFAULT_WIDTH = 450; public static final int DEFAULT_HEIGHT = 350; public static final int STEPS = 1000; public static final int DELAY = 3; public BounceFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); setTitle("Bounce");

  12. Examples of Thread Use BounceThread Program (2): BounceFrame Class //imports public void addButton(Container c, String title, ActionListener listener) { JButton button = new JButton(title); c.add(button); button.addActionListener(listener); } public void addBall() { Ball b = new Ball(); panel.add(b); Runnable r = new BallRunnable(b, panel); Thread t = new Thread(r); t.start( ); } } //end BouceFrame • addButton( ) • Creates button, JButton • Adds button to c, Continer • addBall ( ) • Creates aBall, Ball • Adds aBall to panel • Creates r, an instance of BallRunable(…) • Passes BallRunable aBall & panel • Creates t, Thread • Calls t.start()

  13. Runnable Interface • java.lang Interface Runnable • void run( ) • Object implementing interface Runnable • Creates a thread • Start the thread: start( ) causes object's run( ) to execute • run( ) can be called in that separately executing thread

  14. Examples of Thread Use BounceThread Program (2): BallRunable Class • Runs code in a separate thread • Subclass Thread • Put code within run( ) public BallRunnable(Ball aBall, Component aComponent) { ball = aBall; component = aComponent; } public void run() { try { for (int i = 1; i <= STEPS; i++) { ball.move(component.getBounds()); component.repaint(); Thread.sleep(DELAY); } } catch (InterruptedException e) { } } } //end BallRunnable class //imports class BallRunnable implements Runnable { private Ball ball; private Component component; public static final int STEPS = 1000; public static final int DELAY = 5; /** Constructs the runnable. aBall & aPanel on which the ball bounces */

  15. Examples of Thread Use BounceThread Program (2): BallPanel Class • Much like BallCanvas • Creates an ArrayList, balls • Adds aBall to balls • Paints graphics //import class BallPanel extends JPanel { private ArrayList<Ball> balls = new ArrayList<Ball>(); public void add(Ball b) { balls.add(b); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; for (Ball b : balls) { g2.fill(b.getShape()); } } } //end BallPanel

  16. Examples of Thread Use BounceThread Program (2): Ball Class if (x + XSIZE >= bounds.getMaxX()) { x = bounds.getMaxX() - XSIZE; dx = -dx; } if (y < bounds.getMinY()) { y = bounds.getMinY(); dy = -dy; } if (y + YSIZE >= bounds.getMaxY()) { y = bounds.getMaxY() - YSIZE; dy = -dy; } } public Ellipse2D getShape() { return new Ellipse2D.Double(x, y, XSIZE, YSIZE); } } //end Ball class • Moves ball if an edge is reached //imports public class Ball { private static final int XSIZE = 15; private static final int YSIZE = 15; private double x = 0; private double y = 0; private double dx = 1; private double dy = 1; public void move(Rectangle2D bounds) { x += dx; y += dy; if (x < bounds.getMinX()) { x = bounds.getMinX(); dx = -dx; }

  17. Examples of Thread Use BounceThread Program (2): BounceThread Running • Usetwo threads • bouncing ball • GUI events • start( ) makes a new thread Runnable • start( ) calls run() //public class BounceFrame extends JFrame public void addBall() { Ball b = new Ball(); panel.add(b); Runnable r = new BallRunnable(b, panel); Thread t = new Thread(r); t.start( ); } } //BallRunnable class public void run() { try {for (int i = 1; i <= STEPS; i++) { ball.move(component.getBounds()); component.repaint(); Thread.sleep(DELAY); } } catch (InterruptedException e) { } } //end run( )

  18. Examples of Thread Use (2): BounceThread Running //public class BounceFrame extends JFrame public void addBall() { Ball b = new Ball(); panel.add(b); Runnable r = new BallRunnable(b, panel); Thread t = new Thread(r); t.start( ); } } • Never call run( ) {“code”} directly • a thread’s start ( ) indirectly calls run ( ){code} • Code for a new thread executes in run( ) • Thead calls static Thread.sleep (DELAY) //BallRunnable class public void run() { try {for (int i = 1; i <= STEPS; i++) { ball.move(component.getBounds()); component.repaint(); Thread.sleep(DELAY); } } catch (InterruptedException e) { } } //end run( )

  19. How to Use Threads • Event-dispatching thread • event-dispatchingthread holds code for Swing event-handling • Ensures an event handler finishes executing before the next one executes • To avoid deadlock, Swing components are created, modified, and queried only from the event-dispatching thread • Avoiding thread problems • Use invokeLater( ) to create the GUI on the event-dispatching thread private static void createAndShowGUI() { //Create and set up the window. frame = new JFrame("FocusConceptsDemo"); frame = new JFrame("FocusConceptsDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); . …… }

  20. How to Use Threads Event-dispatching thread private static void createAndShowGUI() { . …… } public static void main(String[] args) { //Schedule a job for the event-dispatching thread: //creating and showing this application's GUI javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGUI(); } } ); //end call to SwingUtilities.invokeLater to createAndShowGUI() } //end main

  21. How to Use Threads • Using the invokeLater method • invokeLater( ) request the event-dispatching thread to run certain code • Code is contained in run( ) of a Runnable object • Specify the Runnable object as the argument to invokeLater • invokeLater( ) returns immediately, without waiting for the event-dispatching thread to execute the code. /** example of code using invokeLater (anObject) */ Runnable updateAComponent = new Runnable() { public void run() { component.doSomething(); } }; SwingUtilities.invokeLater(updateAComponent); //SwingUtilities.invokeLater run( )

  22. How to Use Threads • Using the invokeAndWait ( ) method • Similar to invokeLater( ) • invokeAndWait( ) does not return until the event-dispatching thread as executed code • Avoid using invokeAndWait( ) • invokeAndWait( ) can cause deadlock • Use invokeLater( ) instead

  23. How to Use Threads • Using threads to improve performance • Move a time-consuming initialization task out of the main thread, so that GUI comes up faster • Examples of time-consuming tasks include • Making extensive calculations • Blocking for network or disk I/O (loading images, for example) • Move a time-consuming task out of the event-dispatching thread, so that the GUI remains responsive • Perform an operation repeatedly • wait( ) for messages from other programs

  24. Synchronizing Threads • Concurrently running threads share data • Producer/consumer scenarios • Producer generates a stream of data • Consumer consumes the data • For example • One thread (the producer) writes data to a file • Another thread (the consumer) reads data from the same file • Concurrent threads share the same resource: share a file • Thus, threads must be synchronized • Use Object’s wait & notifyAll methods Example: new implementations of get and put for threads • wait on each other • notify each other of their activities

  25. Synchronizing Threads: Consumer • Concurrently running threads share data • Example: new implementations of get and put public synchronized int get() { while (available == false) { try wait(); // wait for Producer to put value } catch (InterruptedException e) { } } //end while available = false; notifyAll(); // notify Producer that value has been retrieved return contents; }//end get()

  26. Synchronizing Threads: Producer • Concurrently running threads share data • Example: new implementations of get and put public synchronized void put(int value) { while (available == true) { try { wait();// wait for Consumer to get value } catch (InterruptedException e) { } } contents = value; available = true; notifyAll(); // notify Consumer that value has been set } //end put

  27. Synchronizing Threads • get( ) loops until the Producer has produced a new value • Each time through the loop, get( ) calls the wait( ) • wait( ) relinquishes lock held by the Consumer on CubbyHole • Producer can get( ) and update CubbyHole • Consumer waits for notification from Producer • If the Producer puts something in the CubbyHole, Produces notifies Consumer by calling notifyAll( ) • Consumer is no longer waiting • available is now true • loop exits • get( )returns value in the CubbyHole • put( ) waits for Consumer to consume current value before allowing Producer to produce a new one

  28. Synchronizing Threads • Get( ) loops until Producer has produced new value • Object contains • wait( ) used in producer/consumer example • waits indefinitely for notification • Two other versions of the wait method • wait(long timeout) wait until the timeout period has elapsed • wait( ) for notification • Timed wait((long) delay) can • Synchronize threads • Replace sleep( ) • wait( ) and sleep( ) delay for requested amount of time • Easily wake up wait( ) with notify( ) • Sleeping thread, Thread.sleep(DELAY) cannot be awakened prematurely

  29. Synchronizing Threads: wait(…) • wait(long timeout, int nanos) • Waits for notification or until timeout milliseconds plus nanos nanoseconds have elapsed. • Note:  • Use timed wait methods to synchronize threads, • Use wait() methods to replace sleep • Both wait and sleep delay for the requested amount of time • Easily wake wait with a notify • A sleeping thread cannot be awakened prematurely • Note: Doesn't matter too much for threads that don't sleep for long, but it could be important for threads that sleep for minutes at a time.

  30. How Sims will Use Threads & ‘Sleep: • Sim0, Sim1 public void simulate() Thread.sleep( (long) (delay )); • Sim2, Sim3 & 4 public synchronized void simulate() ….. ….. ….. try { wait(); // wait until 'notify()ed' } catch(InterruptedException ie) { continue; }

  31. Simulator’s Main Loop--Simulator:Simulate( ) Simulator.java 506 public synchronized void simulate() { double delay; DecimalFormat delayfmt = new DecimalFormat("#.0"); boolean msgWaiting; if (_simControl != null) _simControl.updateStatus(iSimControl.PAUSED); // simulation loop 520 while (!_simulationFinished) { …. try { wait(); // wait until 'notify()ed' } catch(InterruptedException ie) { continue; } }

  32. Simulator’s Main LoopSchedule a Wait Time—Time Until Next Event Simulator.java else // (!_simulationFinished) { if (!_clock.onFastTime()) // not onFastTime { 537 delay = ((double)(getNextEventTime() - _clock.updateSimTime()) / _clock.getSpeedFactor()) try { 549 wait( (int) (delay )); } catch (InterruptedException ie) { continue; } // try-catch 566 else //if (_clock.onFastTime())

  33. Simulator’s Main LoopDiscrete-Event Processing Simulator.java 641 else if … try { _eventCal.processEvent(); } 661 } // if clock-not-paused } // simulation loop 663 } //end simulate( )

  34. DefaultSimControl.javaThread of Execution DefaultSimControl.java 84 public class DefaultSimControl extends JFrame implements iSimControl, ActionListener, ItemListener { public DefaultSimControl() //constructor { super("Simulator Control"); ………. // (69) JButton _resumeB _resumeB = createControlButton("Start", RESUME_COLOR); cp.add(_resumeB); ………. }//end constructor

  35. DefaultSimControl.javaThread of Execution DefaultSimControl.java 84 public class DefaultSimControl extends JFrame implements iSimControl, ActionListener, ItemListener { public DefaultSimControl() { super("Simulator Control"); ………. // (69) JButton _resumeB _resumeB = createControlButton("Start", RESUME_COLOR); cp.add(_resumeB); ………. }//end constructor 153 private JButton createControlButton(String name, Color buttonColor) { JButton controlB = new JButton(name); controlB.addActionListener(this); controlB.setBackground(buttonColor); controlB.setForeground(Color.black); controlB.setBorder(BorderFactory.createEtchedBorder()); controlB.setEnabled(false); return controlB; }

  36. DefaultSimControl.javaThread of Execution 84 public class DefaultSimControl extends JFrame implements iSimControl, ActionListener, ItemListener { public DefaultSimControl() { super("Simulator Control"); ………. } SwingUtilities.invokeLater(changeControlDisplay); } public void updateStatus(int status) { final int simStatus = status; Runnable changeControlDisplay = new Runnable() { public void run() { switch(simStatus) SwingUtilities.invokeLater(changeControlDisplay);

  37. DefaultSimControl.java & GUI Controller public DefaultSimControl() { super("Simulator Control"); public class DefaultSimControl extends JFrame implements iSimControl, ActionListener, ItemListener SwingUtilities.invokeLater(changeControlDisplay); } 250 public void actionPerformed(ActionEvent ev) …. 265 else if (source == _pauseB) { _pauseB.setEnabled(false); _resumeB.setEnabled(true); _realTimeB.setEnabled(false); _fastTimeB.setEnabled(false); _speedCBX.setEnabled(false);

  38. GUI Controller 250 public void actionPerformed(ActionEvent ev) …. if (_FirstPause) { _resumeB.setText("Resume"); _FirstPause = false; } 280 _simulator.pause(); }

  39. GUI Controller:Back to Simulator: Simulate Simulator.java 1045 public synchronized void pause() { 1049 _clock.pause(); //paused simulator if (_simControl != null) _simControl.updateStatus(iSimControl.PAUSED); //tell contrller if (_broadcaster != null) _broadcaster.pauseSim(getTimeNow()); //tell interface log("Simulation paused."); notifyAll(); //wake up threads } Clock.java 283 public void pause() { _pauseTime = _currentSimTime.getTime(); _paused = true; }

More Related