Nothing Special   »   [go: up one dir, main page]

Exception Handling and Threads

Download as pdf or txt
Download as pdf or txt
You are on page 1of 14

Exception Handling

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.

Advantage of Exception Handling

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

Difference between checked and unchecked exceptions

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

Java try block is used to enclose the code that might throw an exception. It must be used within
the method.

Java try block must be followed by either catch or finally block.

Syntax of java try-catch

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

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

Let's try to understand the problem if we don't use try-catch block.

public class Testtrycatch1{


public static void main(String args[]){
int data=50/0;//may throw exception
System.out.println("rest of the code...");
}}
Output:
Exception in thread main java.lang.ArithmeticException:/ by zero

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.

Solution by exception handling

Let's see the solution of above problem by java try-catch block.

public class Testtrycatch2{


public static void main(String args[]){
try{
int data=50/0;
}catch(ArithmeticException e){System.out.println(e);}
System.out.println("rest of the code...");
}}
1. Output:

Now, as displayed in the above example, rest of the code is executed i.e. rest of the code...
statement is printed.

Java Multi catch block

If you have to perform different tasks at the occurrence of different Exceptions, use java multi
catch block.

Let's see a simple example of java multi-catch block.

1. public class TestMultipleCatchBlock{


2. public static void main(String args[]){
3. try{
4. int a[]=new int[5];
5. a[5]=30/0;
6. }
7. catch(ArithmeticException e){System.out.println("task1 is completed");}
8. catch(ArrayIndexOutOfBoundsException e){System.out.println("task 2 completed");
9. }
10. catch(Exception e){System.out.println("common task completed");
11. }
12. System.out.println("rest of the code...");
13. } }
Java nested try example

Let's see a simple example of java nested try 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.

Java finally block is always executed whether exception is handled or not.


Java finally block follows try or catch block.

Usage of Java finally

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...");
}
}

Java throw keyword

The Java throw keyword is used to explicitly throw an exception.

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.

The syntax of java throw keyword is given below.

throw exception;
Output:5
finally block is always executed
rest of the code..

Java throw keyword example

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.

public class TestThrow1{


static void validate(int age){
if(age<18)
throw new ArithmeticException("not valid");
else
System.out.println("welcome to vote");
}
public static void main(String args[]){
validate(13);
System.out.println("rest of the code...");
} }

Output:

Exception in thread main java.lang.ArithmeticException:not valid

Java throws keyword

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.

Syntax of java throws


1. return_type method_name() throws exception_class_name{
2. //method code
3. }
4.

Java throws example

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:

Java Custom Exception


Multithreading
Multithreading in java is a process of executing multiple threads simultaneously.

Thread is basically a lightweight sub-process, a smallest unit of processing. Multiprocessing and


multithreading, both are used to achieve multitasking.

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.

Java Multithreading is mostly used in games, animation etc.

Advantages of Java Multithreading

1) It doesn't block the user because threads are independent and you can perform multiple
operations at same time.

2) You can perform many operations together so it saves time.

3) Threads are independent so it doesn't affect other threads if exception occur in a single thread.

Life cycle of a Thread (Thread States)

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

There are two ways to create a thread:

1. By extending Thread class


2. By implementing Runnable interface.

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.

Commonly used Constructors of Thread class:

Thread()
Thread(String name)
Thread(Runnable r)
Thread(Runnable r,String name)

Commonly used methods of Thread class:

1. public void run(): is used to perform action for a thread.


2. public void start(): starts the execution of the thread.JVM calls the run() method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep (temporarily
cease execution) for the specified number of milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10. public Thread currentThread(): returns the reference of currently executing thread.
11. public int getId(): returns the id of the thread.
12. public Thread.State getState(): returns the state of the thread.
13. public boolean isAlive(): tests if the thread is alive.
14. public void yield(): causes the currently executing thread object to temporarily pause and allow
other threads to execute.
15. public void suspend(): is used to suspend the thread(depricated).
16. public void resume(): is used to resume the suspended thread(depricated).
17. public void stop(): is used to stop the thread(depricated).
18. public boolean isDaemon(): tests if the thread is a daemon thread.
19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
20. public void interrupt(): interrupts the thread.
21. public boolean isInterrupted(): tests if the thread has been interrupted.
22. public static boolean interrupted(): tests if the current thread has been interrupted.

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.

Java Thread Example by extending Thread class

class Multi extends Thread{


public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}}
Output:thread is running...

Java Thread Example by implementing Runnable interface


class Multi3 implements Runnable{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi3 m1=new Multi3();
Thread t1 =new Thread(m1);
t1.start();
}}
Output:thread is running...

Priority of a Thread (Thread Priority):


Each thread have a priority. Priorities are represented by a number between 1 and 10. In most
cases, thread schedular schedules the threads according to their priority (known as preemptive
scheduling). But it is not guaranteed because it depends on JVM specification that which
scheduling it chooses.

3 constants defined in Thread class:

1. public static int MIN_PRIORITY


2. public static int NORM_PRIORITY
3. public static int MAX_PRIORITY

Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is 1 and


the value of MAX_PRIORITY is 10.

Example of priority of a Thread:


class TestMultiPriority1 extends Thread{
public void run(){
System.out.println("running thread name is:"+Thread.currentThread().getName());
System.out.println("running thread priority is:"+Thread.currentThread().getPriority());
}
public static void main(String args[]){
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}}
Output:running thread name is:Thread-0
running thread priority is:10
running thread name is:Thread-1
running thread priority is:1

Synchronization and Inter Thread Communication

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

Java synchronized method

If you declare any method as synchronized, it is known as synchronized method.


Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object
and releases it when the thread completes its task.

/* 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);
}

synchronized void deposit(int amount){


balance = balance + amount;
System.out.println( amount + " is deposited");
displayBalance();
}

synchronized void withdraw(int amount){


balance = balance - amount;
System.out.println( amount + " is withdrawn");
displayBalance();
}
}

class TransactionDeposit implements Runnable{


int amount;
Account accountX;
TransactionDeposit(Account x, int amount){
accountX = x;
this.amount = amount;
new Thread(this).start();
}

public void run(){


accountX.deposit(amount);
}
}

class TransactionWithdraw implements Runnable{


int amount;
Account accountY;

TransactionWithdraw(Account y, int amount) {


accountY = y;
this.amount = amount;
new Thread(this).start();
}

public void run(){


accountY.withdraw(amount);
}
}

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.

Example of inter thread communication in java

Let's see the simple example of inter thread communication.

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();
}}

You might also like