310 likes | 325 Views
Advanced Flow of Control. Joe Komar. Advanced Flow of Control. Exceptions -- to catch and process “exceptions” such as I/O errors Threads -- multiple paths through the same program “at the same time”. Exceptions.
E N D
Advanced Flow of Control Joe Komar Komar Associates
Advanced Flow of Control • Exceptions -- to catch and process “exceptions” such as I/O errors • Threads -- multiple paths through the same program “at the same time” Komar Associates
Exceptions • Exception -- “thrown” by program or runtime environment and can be “caught” and handled • Error -- similar to an exception but represents an unrecoverable situation and should not be handled • Java: • Exception and Error classes derived from the Throwable class • Specific exceptions and errors derived from their classes Komar Associates
Exception Execution Flow • Distinguish Exception flow from Normal flow • Debugging is made easier (pinpoint errors) • Java API classes often throw exceptions, letting the programmer decide what to do with them • “Normal” flow is typically 20% of the total code • Some programs should never abnormally abort • Deal with exceptions by: • choosing not to handle them (abnormal abort) • handle the exception where it occurs • handle the exception at another point Komar Associates
Unhandled Exception // Throws an Exception public class Zero { public static void main (String[], args) { int numerator = 10; int denominator = 0; System.out.println (numerator / denominator); } //method main }// class Zero Java.lang.ArithmeticException: / by zero at Zero.main(Zero.java:7) Komar Associates
The try Statement • The try statement identifies a block of statements that may throw an exception • There can be a number of catch blocks following the try block that can process different types of errors try { statement-list } catch (exception-class1 variable) { statement-list } catch (exception-class2 variable) { statement-list } catch …. Komar Associates
Adding Example import java.io.*; public class Adding { public static void main (String[] args) { int num1 = User_Reader.get_integer ("Enter a number: "); int num2 = User_Reader.get_integer ("Enter another number: "); System.out.println ("The Sum is " + (num1 + num2)); }// method main }// class Adding Komar Associates
Adding (cont’d) class User_Reader { public static int get_integer (String prompt) { BufferedReader stdin = new BufferedReader (new InputStreamReader (System.in),1); int number = 0; boolean valid = false; Komar Associates
Adding (cont’d) while (! valid) { System.out.print (prompt); System.out.flush (); try { number = Integer.parseInt (stdin.readLine()); valid = true; } catch (NumberFormatException exception) { System.out.println ("Invalid input. Try again."); } catch (IOException exception) { System.out.println ("Input problem. Terminating."); System.exit(0); } } // while loop return number; }// method get_integer }// class User_Reader Komar Associates
Adding Output Normal Execution Exception handling Enter a number: 8 Enter another number: joe Invalid input. Try again. Enter another number: 34 The Sum is 42 Enter a number: 6 Enter another number: 56 The Sum is 62 Komar Associates
Exception Propagation • Exceptions generated at called methods can be caught at the calling level • Method .getMessage() will return the text of the exception message • Method .printStackTrace() prints the stack trace showing where the exception occurred • The throws clause must be used for “checked exceptions” that are not caught and handled Komar Associates
The throw Statement • The programmer can throw his/her own exception • The throw statement causes transfer to the first applicable catch clause • If the thrown variable is not caught, the program ends abnormally • Can be used to catch application level errors and exceptions Komar Associates
The finally Clause • Executed no matter how the try block is exited • if no exception is generated, the finally block is done after the try block • if an exception occurs, the appropriate catch block is executed and then the finally block • A finally block should be listed after all catch blocks • Typically used to make sure that some section of code is always executed no matter what exceptions might occur Komar Associates
Threads task task task task task task Concurrent flow Sequential flow Komar Associates
Creating Threads • extend the class Thread • must then override the run() method of the Thread class • implement the Runnable interface • must implement the run() method • must then pass this object as a parameter to the constructor of a new Thread object • advantage of allowing the threaded object to belong to its own class heirarchy Komar Associates
Simultaneous public class Simultaneous { public static void main (String[]args) { Soda one = new Soda ("Coke"); Soda two = new Soda ("Pepsi"); Soda three = new Soda ("Seven Up"); one.start(); two.start(); three.start(); try { System.in.read();} catch (Exception e) {} }// method main }// class Simultaneous Komar Associates
Simultaneous class Soda extends Thread { private String name; Soda (String str) { name = str; }// constructor public void run() { for (int count = 0; count < 5; count++) System.out.println (name); }// method run }// class Soda Komar Associates
Simultaneous Output Komar Associates
Threads Issues • Simultaneous access to the same data • Use the synchronized modifier on a method • Only one thread can then use that method at one time • Actually locks all synchronized methods for that object • Synchronization without the modifier: synchronized (expression) statement (usually a block) Komar Associates
Additional Thread Methods • suspend() -- temporarily halts execution of a thread • resume() -- resumes a suspended thread’s execution where it left off • sleep (long milliseconds) -- suspends the thread for the specified number of milliseconds Komar Associates
Bouncing Ball 2 import java.awt.*; import java.applet.*; import java.awt.event.*; public class Bouncing_Ball2 extends Applet { // private final int PAUSE = 100000; private final int SIZE = 300; private Ball2 ball = new Ball2 (150,10,250,200); private Graphics page; private Control_Panel controls; public void init() { setVisible (true); setSize (SIZE,SIZE); page = getGraphics(); page.setXORMode (getBackground()); }// method init Komar Associates
Bouncing Ball 2 public void start() { controls = new Control_Panel (Thread.currentThread()); controls.start(); ball.pause(); while (ball.moving()) ball.bounce (page); }// method start }// class Bouncing_Ball2 Komar Associates
Bouncing Ball 2 class Control_Panel extends Thread { private Button suspend = new Button ("suspend"); private Button resume = new Button ("resume"); private Frame frame = new Frame ("Bouncing Ball Control Panel"); private Thread applet_thread; Control_Panel (Thread applet_thread){ this.applet_thread = applet_thread; }// constructor Komar Associates
Bouncing Ball 2 public void run (){ Resume_Action resume_action = new Resume_Action (applet_thread); Suspend_Action suspend_action = new Suspend_Action (applet_thread); suspend.addActionListener (suspend_action); resume.addActionListener (resume_action); frame.setLayout (new FlowLayout()); frame.add (suspend); frame.add (resume); frame.pack(); frame.setLocation (250, 250); frame.setVisible (true); }// method run }// class Control_Panel Komar Associates
Bouncing Ball 2 class Suspend_Action implements ActionListener { Thread applet_thread; Suspend_Action (Thread applet_thread) { this.applet_thread = applet_thread; }// constructor public void actionPerformed (ActionEvent action){ applet_thread.suspend(); }// method actionPerformed }// class Suspend_Action Komar Associates
Bouncing Ball 2 class Resume_Action implements ActionListener { Thread applet_thread; Resume_Action (Thread applet_thread) { this.applet_thread = applet_thread; }// constructor public void actionPerformed (ActionEvent action){ applet_thread.resume(); }// method actionPerformed }// class Resume_Action Komar Associates
Bouncing Ball 2 class Ball2 { private final int MOVE = 2; private final float DISTANCE = 0.97f; private final int SIZE = 20; private final int PAUSE = 5; private int x; private int start_y; private int end_y; private int length; private boolean moving_up = true; Ball2 (int new_x, int new_start_y, int new_end_y, int new_length) { x = new_x; start_y = new_start_y; end_y = new_end_y; length = new_length; }// constructor Komar Associates
Bouncing Ball 2 public void pause() { try { Thread.currentThread().sleep(PAUSE); } catch (InterruptedException exception) { System.out.println ("have an exception"); } }// method pause Komar Associates
Bouncing Ball 2 void move() { if (moving_up) end_y = end_y - MOVE; else end_y = end_y + MOVE; }// method move void draw_ball (Graphics page) { page.drawOval (x-(SIZE/2), end_y, SIZE, SIZE); page.drawLine (x, start_y, x, end_y); }// method draw_ball Komar Associates
Bouncing Ball 2 public boolean moving (){ return length != 0; }// method moving public void bounce (Graphics page) { for (int count = 1; count < length; count += MOVE) { draw_ball (page); pause(); draw_ball(page); move(); } moving_up = !moving_up; length = (int) (DISTANCE * length); }// method bounce }//class Ball2 Komar Associates
Bouncing Ball2 Bouncing Ball 2 in Action Komar Associates