Exception Handling and Threads
Exception Handling and Threads
Exception Handling and Threads
The exception handling in java is one of the powerful mechanism to handle the runtime errors so
that normal flow of the application can be maintained.
What is exception
In java, exception is an event that disrupts the normal flow of the program. It is an object which is
thrown at runtime.
The core advantage of exception handling is to maintain the normal flow of the application. Exception
normally disrupts the normal flow of the application that is why we use exception handling.
Types of Exception
There are mainly two types of exceptions: checked and unchecked where error is considered as
unchecked exception. The sun microsystem says there are three types of exceptions:
1. Checked Exception
2. Unchecked Exception
3. Error
1) Checked Exception: The classes that extend Throwable class except RuntimeException and Error
are known as checked exceptions e.g.IOException, SQLException etc. Checked exceptions are
checked
at compile-time.
2) Unchecked Exception: The classes that extend RuntimeException are known as unchecked
exceptions e.g. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc.
Unchecked exceptions are not checked at compile-time rather they are checked at runtime.
3) Error: Error is irrecoverable e.g. OutOfMemoryError, VirtualMachineError, AssertionErroretc.
Hierarchy of Java Exception classes
Checked and UnChecked Exceptions
Java try block is used to enclose the code that might throw an exception. It must be used within
the method.
1. try{
2. //code that may throw exception
3. }catch(Exception_class_Name ref){}
Syntax of try-finally block
1. try{
2. //code that may throw exception
3. }finally{}
Java catch block is used to handle the Exception. It must be used after the try block only.
You can use multiple catch block with a single try.
Problem without exception handling
As displayed in the above example, rest of the code is not executed (in such case, rest of the
code... statement is not printed).
There can be 100 lines of code after exception. So all the code after exception will not be
executed.
Now, as displayed in the above example, rest of the code is executed i.e. rest of the code...
statement is printed.
If you have to perform different tasks at the occurrence of different Exceptions, use java multi
catch block.
class Excep6{
public static void main(String args[]){
try{
try{
System.out.println("going to divide");
int b =39/0;
}catch(ArithmeticException e){System.out.println(e);}
try{
int a[]=new int[5];
a[5]=4;
}catch(ArrayIndexOutOfBoundsException e){System.out.println(e);}
System.out.println("other statement);
}catch(Exception e){System.out.println("handeled");}
System.out.println("normal flow..");
}
}
Java finally block
Java finally block is a block that is used to execute important code such as closing connection,
stream etc.
Case 1
Let's see the java finally example where exception doesn't occur.
class TestFinallyBlock{
public static void main(String args[]){
try{
int data=25/5;
System.out.println(data);
}
catch(NullPointerException e){System.out.println(e);}
finally{System.out.println("finally block is always executed");}
System.out.println("rest of the code...");
}
}
We can throw either checked or uncheked exception in java by throw keyword. The throw
keyword is mainly used to throw custom exception. We will see custom exceptions later.
throw exception;
Output:5
finally block is always executed
rest of the code..
In this example, we have created the validate method that takes integer value as a parameter. If the age
is less than 18, we are throwing the ArithmeticException otherwise print a message welcome to vote.
Output:
The Java throws keyword is used to declare an exception. It gives an information to the
programmer that there may occur an exception so it is better for the programmer to provide the
exception handling code so that normal flow can be maintained.
Exception Handling is mainly used to handle the checked exceptions. If there occurs any
unchecked exception such as NullPointerException, it is programmers fault that he is not
performing check up before the code being used.
Let's see the example of java throws clause which describes that checked exceptions can be
propagated by throws keyword.
import java.io.IOException;
class Testthrows1{
void m()throws IOException{
throw new IOException("device error");//checked exception
}
void n()throws IOException{
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("exception handled");}
}
public static void main(String args[]){
Testthrows1 obj=new Testthrows1();
obj.p();
System.out.println("normal flow..."); } }
Output:
But we use multithreading than multiprocessing because threads share a common memory area.
They don't allocate separate memory area so saves memory, and context-switching between the
threads takes less time than process.
1) It doesn't block the user because threads are independent and you can perform multiple
operations at same time.
3) Threads are independent so it doesn't affect other threads if exception occur in a single thread.
A thread can be in one of the five states. According to sun, there is only 4 states in thread life
cycle in java new, runnable, non-runnable and terminated. There is no running state.
But for better understanding the threads, we are explaining it in the 5 states.
The life cycle of the thread in java is controlled by JVM. The java thread states are as follows:
1. New
2. Runnable
3. Running
4. Non-Runnable (Blocked)
5. Terminated
How to create thread
Thread class:
Thread class provide constructors and methods to create and perform operations on a
thread.Thread class extends Object class and implements Runnable interface.
Thread()
Thread(String name)
Thread(Runnable r)
Thread(Runnable r,String name)
Runnable interface:
The Runnable interface should be implemented by any class whose instances are intended to be
executed by a thread. Runnable interface have only one method named run().
1. public void run(): is used to perform action for a thread.
Starting a thread:
start() method of Thread class is used to start a newly created thread. It performs following
tasks:
A new thread starts(with new callstack).
The thread moves from New state to the Runnable state.
When the thread gets a chance to execute, its target run() method will run.
It is already mentioned that threads in Java are running in the same memory space, and hence it is
easy to communicate between two threads. Inter-thread communications allow threads to talk to or
wait on each other. Again, because all the threads in a program share the same memory space, it is
possible for two threads to access the same variables and methods in object. Problems may occur
when two or more threads are accessing the same data concurrently, for example, one thread stores
data into the shared object and the other threads reads data, there can be synchronization problem if
the first thread has not finished storing the data before the second one goes to read it. So we need to
take care to access the data by only one thread process at a time. Java provides unique language level
support for such synchronization. in this Section we will learn how synchronization mechanism and
inter-thread communications are possible in Java.
Synchronization
To solve the critical section problem, one usual concept is known what is called monitor. A monitor is
an object which is used as a mutually exclusive lock ( called mutex). Only one thread may own a
monitor at a given time. When a thread acquires a lock it is said to have entered the monitor. All other
threads attempting to enter the locked monitor will be suspended until the owner thread exits the
monitor. But in Java, there is no such monitor. In fact, all Java object have their own implicit monitor
associated with them. Here, the key word synchronized is used by which method (s) or block of
statements can be made protected from the simultaneous access. With this, when a class is designed
with threads in mind, the class designer decides which methods should not be allowed to execute
concurrently. when a class with synchronized method is instantiated, the new object is given its own
implicit monitor. The entire time that a thread is inside of a synchronized method, all other threads
that try to call any other synchronized method on the same instance have to wait. In order to exit the
monitor and relinquish control of the object to the next waiting thread the monitor owner simply
needs to return from the method.
Let us illustrate this mechanism with a simple example.
Suppose, we want to maintain a bank account of customers then Several transactions, such as deposit
some amount to an account and withdraw some amount from an account etc. are possible. Now, for a
given account, if two or more transactions come simultaneously then only one transaction should be
allowed at a time instead of simultaneous transaction processing so that data inconsistency will never
occur. So, what we need is to synchronize the transaction
/* The following Java application shows how the transactions in a bank can be carried out
concurrently. */
class Account {
public int balance;
public int accountNo;
void displayBalance() {
System.out.println("Account No:" + accountNo + "Balance: " + balance);
}
class Demonstration_119{
public static void main(String args[]) {
Account ABC = new Account();
ABC.balance = 1000;
ABC.accountNo = 111;
TransactionDeposit t1;
TransactionWithdraw t2;
t1 = new TransactionDeposit(ABC, 500);
t2 = new TransactionWithdraw(ABC,900);
}
}
Output
500 is deposited
Account No:111Balance: 1500
900 is withdrawn
Account No:111Balance: 600
Inter-thread Communication
There are three ways for threads to communicate with each other. The first is through commonly
shared data. All the threads in the same program share the same memory space. If an object is
accessible to various threads then these threads share access to that object's data member and thus
communicate each other.
The second way for threads to communicate is by using thread control methods. There are such three
methods by which threads communicate for each other:
suspend ( ): A thread can suspend itself and wait till other thread resume it.
resume ( ): A thread can wake up other waiting thread (which is waiting using suspend() ) through its
resume() method and then can run concurrently.
join ( ) :This method can be used for the caller thread to wait for the completion of called thread.
The third way for threads to communicate is the use of three methods; wait(), notify(), and
notifyAll(); these are defined in class Object of package java.lang. Actually these three methods
provide an elegant inter-process communication mechanism to take care the deadlock situation in
Java. As there is multi-threading in program, deadlock may occur when a thread holding the key to
monitor is suspended or waiting for another thread's completion. If the other thread is waiting for
needs to get into the same monitor, both threads will be waiting for ever. The uses of these three
methods are briefed as below:
wait ( ):This method tells the calling thread to give up the monitor and make the calling thread wait
until either a time out occurs or another thread call the same thread's notify() or notifyAll() method.
Notify ( ): This method wakes up the only one (first) waiting thread called wait() on the same object.
notifyAll( ): This method will wake up all the threads that have been called wait( ) on the same object.
class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
synchronized void deposit(int amount){
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class Test{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}
start();
}}