Transcript Lecture 11

Lecture 11(chap 14)
Exception Handling & Thread
Instructors:
Fu-Chiung Cheng
(鄭福炯)
Associate Professor
Computer Science & Engineering
Tatung Institute of Technology
1
Outline
•
•
•
•
•
exception processing
catching and handling exceptions
creating new exceptions
separate process threads
synchronizing threads
1
Exceptions
• An exception is an object that describes an unusual
or erroneous situation
• Exceptions are thrown by a program, and may be
caught and handled by another part of the program
• A program can therefore be separated into a
normal execution flow and an exception execution
flow
• An error is also represented as an object in Java,
but usually represents a unrecoverable situation
2
and should not be caught
Exception Handling
• A program can deal with an exception in one of
three ways:
– ignore it
– handle it where it occurs
– handle it an another place in the program
• The manner in which an exception is processed is
an important design consideration
3
Exception Handling
• If an exception is ignored by the program, the
program will terminate and produce an appropriate
message
• The message includes a call stack trace that
indicates on which line the exception occurred
• The call stack trace also shows the method call
trail that lead to the execution of the offending line
• See Zero.java
4
public class Zero {
public static void main (String[] args) {
int numerator = 10;
int denominator = 0;
System.out.println (numerator / denominator);
} // method main
} // class Zero
The try Statement
• To process an exception when it occurs, the line that
throws the exception is executed within a try block
• A try block is followed by one or more catch clauses,
which contain code to process an exception
• Each catch clause has an associated exception type
• When an exception occurs, processing continues at
the first catch clause that matches the exception type
• See Adding.java
5
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
class User_Reader {
public static int get_integer (String prompt) {
BufferedReader stdin = new BufferedReader
(new InputStreamReader(System.in));
int number = 0;
boolean valid = false;
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);
}
}
return number;
} // method get_integer
} // class User_Reader
Exception Propagation
• If it is not appropriate to handle the exception
where it occurs, it can be handled at a higher level
• Exceptions propagate up through the method
calling hierarchy until they are caught and handled
or until they reach the outermost level
• A try block that contains a call to a method in
which an exception is thrown can be used to catch
that exception
• See Propagation_Demo.java
6
public class Propagation_Demo {
static public void main (String[] args) {
Exception_Scope demo = new Exception_Scope();
System.out.println("program beginning");
demo.level1();
System.out.println("program ending");
} // method main
} // class Propagation_Demo
class Exception_Scope {
public void level3 (int adjustment) {
int current = 1;
System.out.println("level3 beginning");
current = current / adjustment; // divided by zero
System.out.println("level3 ending");
} // method level3
public void level2() {
System.out.println("level2 beginning");
level3 (0);
System.out.println("level2 ending");
} // method level2
public void level1() {
System.out.println("level1 beginning");
try {
level2();
} catch (ArithmeticException problem) {// page 667
System.out.println (problem.getMessage());
problem.printStackTrace();
}
System.out.println("level1 ending");
} // method level1
} // class Exception_Scope
Exceptions
• An exception is either checked or unchecked
• A checked exception can only be thrown within a
try block or within a method that is designated to
throw that exception
• The compiler will complain if a checked exception
is not handled appropriately
• An unchecked exception does not require explicit
handling, though it could be processed that way
7
The throw Statement
• A programmer can define an exception by
extending the appropriate class
• Exceptions are thrown using the throw statement:
throw exception-object;
• See Throw_Demo.java
• Usually a throw statement is nested inside an if
statement that evaluates the condition to see if the
exception should be thrown
8
import java.io.IOException;
public class Throw_Demo {
public static void main (String[] args)
throws Ooops {
Ooops problem = new Ooops ("Alert!");
throw problem;
// execution never gets to this point
} // method main
} // class Throw_Demo
class Ooops extends IOException {
Ooops (String message) {
super (message);
} // constructor Ooops
} // class Ooops
The finally Clause
• A try statement can have an optional clause
designated by the reserved word finally
• If no exception is generated, the statements in the
finally clause are executed after the statements in
the try block complete
• Also, if an exception is generated, the statements
in the finally clause are executed after the
statements in the appropriate catch clause
complete
9
The finally Clause
• Exception Handling:
try {
code that may generate exception;
} catch (exception) {
code to handle the exception;
} finally {
code will be executed;
}
9
Threads
• Processing can be broken into several separate
threads of control which execute at the same time
• "At the same time" could mean true parallelism or
simply interlaced concurrent processing
• A thread is one sequential flow of execution that
occurs at the same time another thread is
executing the statement of the same program
• They are not necessarily executing the same
statements at the same time
10
Threads
• A thread can be created by deriving a new thread
from the Thread class
• The run method of the thread defines the
concurrent activity, but the start method is used
to begin the separate thread process
• See Simultaneous.java
• A thread can also be created by defining a class
that implements the Runnable interface
• By implementing the interface, the thread class
can be derived from a class other than Thread
11
public class Simultaneous {
public static void main (String[] args) {
Soda one = new Soda ("Coke");
Soda two = new Soda ("Pepsi");
Soda three = new Soda ("Diet Coke");
one.start(); two.start(); three.start();
} // method main
} // class Simultaneous
class Soda extends Thread {
private String name;
Soda (String str) { name = str; } // constructor Soda
public void run() {
for (int count = 0; count < 100; count++)
System.out.println (name);
} // method run
} // class Soda
Shared Data
• Potential problems arise when multiple threads
share data
• Specific code of a thread may execute at any point
relative to the processing of another thread
• If that code updates or references the shared data,
unintended processing sequences can occur that
result in incorrect results
12
Shared Data
• Consider two withdrawals from the same bank
account at the same time
task: withdraw 300
Is amount <= balance
balance task: withdraw 300
531
YES
balance -= 300
Is amount <= balance
YES
231
-69
balance -= 300
13
Synchronization
• Multiple threads of control can be made safe if
areas of code that use shared data are synchronized
• When a set of code is synchronized, then only one
thread can be using that code at a time
• The other threads must wait until the first thread is
complete
• This is an implementation of a synchronization
mechanism called a monitor
• See ATM_Accounts.java
14
public class ATM_Accounts {
public static void main (String[] args) {
Savings_Account savings =
new Savings_Account(4321, 531);
ATM west_branch = new ATM (savings);
ATM east_branch = new ATM (savings);
west_branch.start();
east_branch.start();
} } // class ATM_Accounts
class Savings_Account {
protected int account;
protected int balance;
public Savings_Account (int account_num, int initial) {
account = account_num;
balance = initial;
} // constructor Savings_Account
public synchronized boolean withdrawal (int amount) {
boolean result = false;
System.out.println ("Withdrawal from account "
+ account);
System.out.println ("Amount: " + amount);
if (amount <= balance) {
balance -= amount;
System.out.println ("New balance: " + balance);
result = true;
} else
System.out.println ("Insufficient funds.");
System.out.println();
return result;
} // method withdrawal
} // class Savings_Account
class ATM extends Thread {
Savings_Account account;
ATM (Savings_Account savings) {
account = savings;
} // constructor ATM
public void run () {
account.withdrawal (300);
} // method run
} // class ATM
Thread Synchronization
• synchronized statement:
synchronized (expr)
statement;
• expr must result in an object.
• The object is locked while synchronized statement
is executed.
Controlling Threads
• Thread processing can be temporarily suspended,
then later resumed, using methods from the
Thread class
• A thread can also be put to sleep for a specific
amount of time
• These mechanisms can be quite helpful in certain
situations, like controlling animations
• See Bouncing_Ball2.java
15
import java.awt.event.*;
import java.applet.Applet;
import java.awt.*;
public class Bouncing_Ball2 extends Applet {
private final int SIZE = 300;
private Ball ball = new Ball(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
public void start() {
controls = new Control_Panel (Thread.currentThread());
controls.start(); ball.pause();
while (ball.moving())
ball.bounce (page);
} // method start
} // class Bouncing_Ball2
class Control_Panel extends Thread {
private Button suspend = new Button ("suspend");
private Button resume = new Button ("resume");
private Frame frame = new Frame ("B B Control Panel");
private Thread applet_thread;
Control_Panel (Thread applet_thread) {
this.applet_thread = applet_thread;
} // constructor Control_Panel
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, 200); frame.setVisible (true);
} } // class Control_Panel
class Suspend_Action implements ActionListener {
Thread applet_thread;
Suspend_Action (Thread applet_thread) {
this.applet_thread = applet_thread;
} // constructor Suspend_Action
public void actionPerformed(ActionEvent action) {
applet_thread.suspend();
} // method actionPerformed
} // class Suspend_Action
class Resume_Action implements ActionListener {
Thread applet_thread;
Resume_Action (Thread applet_thread) {
this.applet_thread = applet_thread;
} // constructor Resume_Action
public void actionPerformed(ActionEvent action) {
applet_thread.resume();
} // method actionPerformed
} // class Resume_Action
class Ball {
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;
Ball (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 Ball
public void pause() {
try {
Thread.currentThread().sleep (PAUSE);
} catch (InterruptedException exception) {
System.out.println ("have an exception");
} } // method pause
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);
} // draw_ball
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(); // for loop in previous example
draw_ball(page);
move();
}
moving_up = !moving_up;
length = (int) (DISTANCE * length);
} // method bounce
} // class Ball
Conclusion
• Exception handling make a program to separate to
a normal execution flow and an exception execution flow
• Programmers must carefully consider how exception
should be handled.
• Threads: created by A. inheriting from Thread class
B. implementing Runnable interface
• Synchronization may be used to prevent concurrent access
shared data.