Exception Handling, Basics of Multi-Threaded Programs
Exception Handling, Basics of Multi-Threaded Programs
1.Compile-time errors
2.Run-time errors
3.Logical errors.
1.Compile-time errors:
These are syntactical errors found in the code, due to which a program
fails to compile.
For example, forgetting a semicolon at the end of the a java program,
or writing a statement without proper syntax will result in
compilation-time error.
class CError{
public static void main(String args[]){
System.out.println(“Compilation Error…..”)
}
} D:\>javac Cerror.java
CError.java:4: ';' expected
}
^
1 error
2.Run-time errors:
These are the errors which represent inefficiency of the computer
system to execute a particular statement, means computer system
can not process.
For example, division by zero error occur at run-time.
class RError{
public static void main(String args[]){
int a=10,b=0;
System.out.println(“a/b: ”+(a/b));
}
}
D:\>javac RError.java
D:\>java RError
Exception in thread "main" java.lang.ArithmeticException: / by zero
at RError.main(RError.java:4)
3.Logical errors:
These errors depict flaws in the logic of the program.
The programmer might be using a wrong formula or the design of the program
itself is wrong.
Logical errors are not detected either by the java compiler or JVM.
The programmer is solely responsible for them.
Logical errors means the logic of the program is wrong and these are
identified after observing the output.
class LError{
D:\>javac LError.java
int sum(int a,int b){ D:\>java LError
return a-b; Sum is: 10
}
public static void main(String args[]){
LError le=new LError();
System.out.println("Sum is: "+le.sum(20,10));
}
}
What is an Exception?
8
Benefits of exception handling
• It allows us to fix the error.
• It prevents program from automatically terminating.
• Separates Error-Handling Code from Regular Code.
– Conventional programming combines error detection,
reporting, handling code with the regular code, leads to
confusion.
9
Exception-Handling Fundamentals
• A Java exception is an object that describes an exceptional
condition that has occurred in a piece of code.
10
Exception-Handling Fundamentals
• Java exception handling is managed by via five keywords: try,
catch, throw, throws, and finally.
• Code within catch block catch the exception and handle it.
11
• Any exception that is thrown out of a method must be
specified as such by a throws clause.
13
Java Exception class hierarchy
…
EOFException
IOException FileNotFoundException
Exception
ArithmeticException
NullPointerException
RuntimeException
IndexOutOfBoundsException
…
Object Throwable
NoSuchElementException
…
VirtualMachineError
Ex: Stack overflow
Error
Checked
…
Unchecked
14
Contd..
• All exception types are subclasses of the built-in class
Throwable
• Throwable has two subclasses, they are
– Exception
• Represents exceptional conditions that an user program
might want to catch.
Ex:- IOExceptions, RuntimeExceptins ets.
– Error
• Represents exceptional conditions that are not expected
to be caught by user program.
i.e. Stack overflow
15
Contd..
• IOExceptions:-
– The Subclasses IOException represent errors that can
occur during the processing of input and output statements.
• RuntimeExceptions:-
– The subclasses of RuntimeException represent conditions
that arise during the processing of the bytecode that
represent a program.
16
Categories Of Exceptions
• Unchecked exceptions
• Checked exception
17
Characteristics Of Unchecked Exceptions
• The compiler doesn’t require you to catch them if they are
thrown.
– No try-catch block required by the compiler
• Examples:
– NullPointerException,IndexOutOfBoundsException,
ArithmeticException…
18
Common Unchecked Exceptions:
NullPointerException
• arr[i-1] = arr[i-1] / 0;
19
Common Unchecked Exceptions:
ArrayIndexOutOfBoundsException
• int [] arr = null;
• arr[0] = 1;
20
Common Unchecked Exceptions:
ArithmeticExceptions
• int [] arr = null;
• arr[0] = 1;
• arr[i-1] = arr[i-1] / 0;
ArithmeticException
(Division by zero)
21
Checked Exceptions
• Must be handled.
– You must use a try-catch block or throws
• Example:
– IOException etc.
22
Uncaught Exceptions
• If an exception is not caught by user program, then execution of the program
stops and it is caught by the default handler provided by the Java run-time
system
• Default handler prints a stack trace from the point at which the exception
occurred, and terminates the program.
Ex:
class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
Output:
java.lang.ArithmeticException: / by zero
at Exc0.main(Exc0.java:4)
Exception in thread "main"
23
Using try and catch
The catch clause should follow immediately the try block
24
Example
class Ex2{
public static void main(String args[]){
int d,a;
try{ //monitor a block of code
d=0;
a=4/d;
System.out.println("this will not be printed.");
}
catch(ArithmeticException e){ //catch divide-by-zero error
System.out.println("Division by zero");
}
System.out.println("After catch statement");
}
}
Output:
Division by zero.
26
Example:
class MultiCatch2{
public static void main(String args[]){
int d,a;
try{ //monitor a block of code
d=args.length;
a=4/d;
int c[]={2};
c[4]=6;
System.out.println("this will not be printed.");
}
catch(ArithmeticException e){ //catch divide-by-zero error
System.out.println("Division by zero");
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("array index out of bounds");
}
System.out.println("After try/catch statement");
}
}
27
Caution
• Remember that, exception subclass must come before any of
of their superclasses.
28
Example
29
Nested try Statements
• A try statement can be inside the block of another try.
• If an inner try statement does not have a catch, then the next
try statement’s catch handlers are inspected for a match.
30
Example
class NestTry{
public static void main(String args[]){
try{ //monitor a block of code
int a=args.length;
int b=8/a;
System.out.println("a="+a);
try{
if(a==1)
a=a/(a-a);
if (a==2){
int c[]={2};
c[4]=6;
}
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("array index out of bounds: "+e);
}
}
catch(ArithmeticException e){ //catch divide-by-zero error
System.out.println("Division by zero: "+e);
}
System.out.println("After try/catch statement");
}
} 31
Output
• When no parameter is given:
Divide by 0: java.lang.ArithmeticException: / by zero
• When one parameter is given
a=1
Divide by 0: java.lang.ArithmeticException: / by zero
• When two parameters are given
a=2
Array index out-of-bounds:
java.lang.ArrayIndexOutOfBoundsException
32
throws
• If a method is capable of causing an exception that it does not handle, it
must specify this behavior so that callers of the method can guard
themselves against that exception
type method-name( parameter-list) throws exception-list
{
// body of method
}
• It is not applicable for Error or RuntimeException, or any of their
subclasses
33
• C) Write a program to count the number of words in a given
text.
import java.io.*;
import java.util.*;
public class WordsCountC{
public static void main(String args[ ])throws IOException{
long nl=0,nw=0,nc=0;
String line;
BufferedReader br=new BufferedReader(new FileReader(args[0]));
while ((line=br.readLine())!=null){
nl++;
nc=nc+line.length();
StringTokenizer st = new StringTokenizer(line);
nw += st.countTokens();
}
System.out.println("Number of Characters: "+nc);
System.out.println("Number of Words: "+nw);
System.out.println("Number of Lines: "+nl);
}
}
throw
• So far, you have only been catching exceptions that are thrown by the
Java run-time system.
• It is possible for your program to throw an exception explicitly.
General form
throw TrrowableInstance;
• Here, TrrowableInstance must be an object of type Throwable or a
subclass Throwable.
• Simple types, such as int or char, as well as non-Throwable classes,
such as String and Object, cannot be used as exceptions.
• There are two ways to obtain a Throwable objects:
– Using a parameter into a catch clause
– Creating one with the new operator
36
public class TestThrow1{
} catch(NullPointerException e) {
System.out.println("Caught inside demoproc.");
throw e; // rethrow the exception
}
}
• } o/p: Caught inside demoproc.
Recaught: java.lang.NullPointerException: demo
38
• new is used to construct an instance of NullPointerException.
• All of Java’s built-in run-time exceptions have at least two constructors:
– One with no parameter
– Another one that takes a string parameter.
• The string parameter is used to describe exception.
39
finally
• The finally block is a block that is always executed. It is mainly used to
perform some important tasks such as closing connection, stream etc.
• finally creates a block of code that will be executed after try/catch block has
completed and before the code following the try/catch block.
• The finally clause is also executed whenever the control is about to return to
the caller from inside a try/catch block, via an explicit return tatement.
• finally clause will execute whether or not an exception is thrown.
• The finally clause is optional.
• Each try statement requires at least one catch or a finally clause.
40
case 1
finally{
System.out.println("finally block always executed");
}
System.out.println("rest of the code");
}
}
case 2
class FinallyDemo {
public static void main(String args[]) {
try {
int c=25/0;
} catch (NullPointerException e)
{
System.out.println("Exception caught");
}
finally{
System.out.println("finally block always executed");
}
System.out.println("rest of the code");
}
}
42
case 3
finally{
System.out.println("finally block always executed");
}
System.out.println("rest of the code");
}
}
Java’s Built-in Exceptions
• Java defines several exception classes in java.lang package and java.io
package.
Exception Meaning
ArithmeticException Arithmetic error, such as divide-by-
zero.
44
NumberFormatException
Ex:- int n=Integer.parseInt(“a”);
ClassCastException
Ex:- Here Ball is base class and SoftBall is derived class.
Ball b = new SoftBall(); Ball b=new Ball();
SoftBall s = (SoftBall)b; SoftBall s=(SoftBall)b;
45
Checked exceptions defined in java.io
Exception Meaning
46
Creating Your Own Exception Subclasses
47
The Methods Defined by Throwable
Method Description
void printStackTrace( ) Displays the stack trace.
48
class MyException extends Exception {
private int detail; public static void main(String args[]) {
try {
MyException(int a) {
compute(1);
detail = a; compute(20);
} }
public String toString() { catch (MyException e) {
return "MyException[" + detail + "]"; System.out.println("Caught " + e);
}
}
}
} }
class ExceptionDemo {
static void compute(int a) throws MyException {
System.out.println("Called compute(" + a + ")");
if(a > 10)
throw new MyException(a); Output:
System.out.println("Normal exit"); Called compute(1)
} Normal exit
Called compute(20)
Caught MyException[20]
49
6. Modify the withdraw() method of Account class such that this method
should throw “InsufficientFundException” if the account holder tries to
withdraw an amount that leads to condition where current balance
becomes less than minimum balance otherwise allow the account holder
to withdraw and update balance accordingly.
import java.util.Scanner;
class InsufficientException extends Exception{
double balance;
double wbalance;
public InsufficientException(String msg){
super(msg);
}
void withdraw(){
Scanner in=new Scanner(System.in);
double balance=in.nextDouble();
;
System.out.println("Current Balance: "+balance);
try{
System.out.print("Enter withdraw amount greater than 100: ");
double wamount= in.nextDouble();
if(wamount>balance){
throw new InsufficientException("Insufficient balance in account.....");
}
else
System.out.println("Transaction Successfully Completed...............");
double rembal=balance-wamount;
System.out.println("Withdrawal Amount :"+wamount);
System.out.println("After transaction current balance:"+rembal); }
catch(InsufficientException e){
System.out.println("Caught:"+e.getMessage());
}
}
}
class ExecuteAccount6{
public static void main(String args[]) {
InsufficientException ie=new InsufficientException("Insufficient balance in account");
ie.withdraw();
}
}
Basics of Multi-threaded Programs
Single Tasking
A task means doing some calculation, processing, etc.
This means we are wasting a lot of processor time and processor has to
sit idle without any job for a long time.
In this, most of the processor time is getting engaged and it is not sitting
idle.
Uses:
• Process is heavyweight.
• Switching from one process to another require some time for saving and
loading registers, memory maps, updating lists etc.
Processor
The Operating
System assigns
processor time
to each task
60
2) Thread-based Multitasking (Multithreading)
• Threads share the same address space.
• Thread is lightweight.
• Cost of communication between the thread is low.
• For instance, a text editor can format text at the same time that it is printing,
as long as these two actions are being performed by two separate threads
Thread Based Multitasking
Task A
T2
Processor T1
T0
A Threading
library creates
threads and
assigns
processor time
to each thread
62
What is Thread in java
• A thread is a lightweight sub process, a smallest unit of processing.
• It is a separate path of execution.
• Threads are independent, if there occurs exception in one thread, it doesn't
affect other threads.
• It shares a common memory area.
OS
Note: At least one process is required for each thread.
At a time one thread is executed only.
Thread Life Cycle
• Thread can exist in several states:
• New (Born) State:
After the creations of Thread instance the thread is in this state but before the
start() method invocation. At this point, the thread is considered not alive.
A thread first enters runnable state after the invoking of start() method but a
thread can return to this state after either running, waiting, sleeping or
coming back from blocked state also.
There are several ways to enter in Runnable state but there is only one way to
enter in Running state: the scheduler select a thread from runnable pool.
• Blocked State:
A thread can enter in this state because of waiting the resources that are
hold by another thread.
• Dead State:
A thread can be considered dead when its run() method completes.
If any thread comes on this state that means it cannot ever run again.
Schedular dispatch
Thread Life Cycle (Contd..)
Starting from the birth of a thread, till its death, a thread exists in different states
which are collectively called “Thread Life Cycle”.
That is void start() method is used to call the public void run() method.
From runnable state, a thread may get into not-runnable state, when sleep() or
wait() or suspend() methods act on it.
notify() and resume() methods are used to restart waiting and suspended
threads respectively.
Thread Life Cycle (Contd..)
69
How to create thread
There are two ways to create a thread:
1. By extending Thread class
2. By implementing Runnable interface.
Thread Class Constructors
1. Thread() Allocates a new Thread Object.
E.g., Thread t=new Thread();
Where group is the thread group, target is the object whose run method is called.
When a Java program starts up, one thread begins running immediately.
This is usually called the main thread of your program, because it is the one that
is executed when your program begins.
But when we write extends Thread, there is no scope to extend another class, as multiple
inheritance is not supported in java.
If we write implements Runnable, then still there is scope to extend another class.
This is definitely advantageous when the programmer wants to use threads and also
wants to access the features of another class.
join()
• Often we want the main thread to finish last.
• It does not happen automatically.
• We uses join( ) to ensure that the main thread is the
last to stop.
84
Creates thread t
Main thread
Calls t.Join()
Main thread
resumes
85
// Using join() to wait for threads to finish.
class NewThread implements Runnable { class DemoJoin {
String name; // name of thread public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
Thread t; NewThread ob2 = new NewThread("Two");
NewThread(String threadname) { NewThread ob3 = new NewThread("Three");
name = threadname; System.out.println("Thread One is alive: "+ ob1.t.isAlive());
t = new Thread(this, name); System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println("New thread: " + t); System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
t.start(); // Start the thread
// wait for threads to finish
} try {
System.out.println("Waiting for threads to finish.");
// This is the entry point for thread. ob1.t.join();
public void run() { ob2.t.join();
try { ob3.t.join();
for(int i = 5; i > 0; i--) { } catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
System.out.println(name + ": " + i); }
Thread.sleep(1000);
} System.out.println("Thread One is alive: "+ ob1.t.isAlive());
} catch (InterruptedException e) { System.out.println("Thread Two is alive: "+ ob2.t.isAlive());
System.out.println(name + " interrupted."); System.out.println("Thread Three is alive: "+ ob3.t.isAlive());
} System.out.println("Main thread exiting.");
}
System.out.println(name + " exiting."); }
}
}
Synchronization
• When two or more threads need access to a shared resource, they need
some way to ensure that the resource will be used by only one thread at a
time.
87
Ex:-
Check availability
Reserve seat
Check
availability
Check availability
Reserve seat
Reserve seat
Seat reservation
database
88
Synchronization can be achieved in two ways:
1) Method level synchronization or synchronized method
2) Block level synchronization or synchronized statements
In method level synchronization the total data of method is sensitive. Where as in block
level synchronization part of the method is sensitive .
Using Synchronized Methods
• Every object with synchronized methods is a monitor.
• When the synchronized method is invoked, the object is locked. All other
threads attempting to invoke synchronized methods must wait.
90
• class Callme{//Without Synchronization
• void call(String msg) {
• System.out.print("["+msg);
• try{
• Thread.sleep(1000); class Synch{
• } public static void main(String args[]){
• catch(InterruptedException e){ Callme target=new Callme();
System.out.println("Interrupted"); Caller ob1=new Caller(target,"hello");
• } Caller ob2=new Caller(target,"Synchronized");
• System.out.println("]"); Caller ob3=new Caller(target,"World");
• }}
• class Caller implements Runnable{ try{
• String msg; ob1.t.join();
• Callme target; ob2.t.join();
• Thread t; ob3.t.join();
• public Caller(Callme targ,String s){ }
• target=targ;msg=s; catch(InterruptedException e){
• t=new Thread(this); System.out.println("Interrupted");
• t.start(); }
• } }
• public void run(){ }
• target.call(msg);
• }
• }
91
• class Callme{//With Synchronization
• synchronized void call(String msg) {
• System.out.print("["+msg);
• try{ class Synch{
• Thread.sleep(1000); public static void main(String args[]){
• } Callme target=new Callme();
• catch(InterruptedException e){ Caller ob1=new Caller(target,"hello");
System.out.println("Interrupted"); Caller ob2=new Caller(target,"Synchronized");
• } Caller ob3=new Caller(target,"World");
• System.out.println("]");
• }} try{
• class Caller implements Runnable{ ob1.t.join();
• String msg; ob2.t.join();
• Callme target; ob3.t.join();
• Thread t; }
• public Caller(Callme targ,String s){ catch(InterruptedException e){
• target=targ;msg=s; System.out.println("Interrupted");
• t=new Thread(this); }
• t.start();
}
• }
}
• public void run(){
• target.call(msg);
• }
• }
92
• class BlockSyn implements Runnable{ /Example for block level synchronization
• public void run(){
• display();
• } first
• public void display(){
• System.out.println(Thread.currentThread().getName());
second
• synchronized(this){ i value is:0
• for(int i=0;i<3;i++){ i value is:1
• try{
• Thread.sleep(1000); i value is:2
• System.out.println("i value is:"+i); i value is:0
• } i value is:1
• catch(Exception e){
• System.out.println(e); i value is:2
• }
• }
• }
• }
public static void main(String args[]){
BlockSyn s= new BlockSyn();
Thread t1= new Thread(s,"first");
Thread t2= new Thread(s,"second");
t1.start();
t2.start();
}
Interthread Communication
• Java uses wait(),notify() and notifyAll() to perform Interthread
Communication.
– wait( ) tells the calling thread to give up the monitor and go to sleep
until some other thread enters the same monitor and calls notify( ).
– notify( ) wakes up the first thread that called wait( ) on the same
object.
– notifyAll( ) wakes up all the threads that called wait( ) on the same
object.The highest priority thread will run first.
• These methods are implemented as final in Object class, as shown below.
– final void wait( ) throws InterruptedException
– final void notify( )
– final void notifyAll( )
94