IT Unit 6 - Multi Threaded Programming and Exception Handling-1
IT Unit 6 - Multi Threaded Programming and Exception Handling-1
By,
Asmatullah Khan,
CL/CP, GIOE,
Secunderabad.
Contents
1. Explain the thread model of Java.
2. Explain thread priorities.
3. Explain the concept of synchronization.
4. Implement the thread class and runnable interface.
5. Illustrate the creation of a thread
6. Illustrate the creation of multiple threads.
7. Describe alive( ), join ( ), suspend( ), resume( ) methods.
8. Explain Inter thread communication.
9. Explain dead lock.
10. Explain the sources of errors.
11. Write the advantages of Exception handling.
12. Explain how to deal with exceptions.
13. Explain the types of Exceptions
14. Explain the concept of Multi-catch statements programs.
A thread is a basic execution unit which has its own
program counter, set of the register, stack but it shares
the code, data, and file of the process to which it belongs.
MultiTasking
• A thread is a:
▫ Facility to allow multiple activities within a single process
▫ Referred as lightweight process
▫ A thread is a series of executed statements
▫ Each thread has its own program counter, stack and local
variables
▫ A thread is a nested sequence of method calls
▫ It shares memory, files and per-process state
Thread model of Java cont…
• Every Java Program has a default main thread.
▫ A thread is an independent path of code execution.
• Many threads can run concurrently in a Java Program.
• Threads can be used to perform time-intensive tasks and run them in the background.
▫ This allows the application to remain responsive to its users.
• Each thread executes runnable object.
▫ Runnables are objects that encapsulate code sequences.
• Threads can initiate an asynchronous task.
▫ Asynchronous indicates that it can run concurrently [at the same time instead of
sequentially]
• The JVM gives each thread its own private JVM stack.
▫ This prevents threads from interfering with each other.
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Lifecycle – Newborn State
• When we create a thread object, the thread is born and is said to be in newborn state.
• The thread is not yet scheduled for running. At this state, we can do only one of the
following with it:
1. Schedule it for running using start() method.
2. Kill it using stop() method.
State diagram of a Thread
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Lifecycle – Runnable state (start())
• The runnable state means that the thread is ready for execution and is waiting for the availability of
the processor.
• That is, the thread has joined the queue of threads that are waiting for execution.
• If all threads have equal priority, then they are given time slots for execution in round robin fashion.
i.e. firstcome, first-serve manner.
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Lifecycle – Running state
• Running means that the processor has given its time to the thread for its
execution.
• The thread runs until it relinquishes control on its own or it is preempted by
a higher priority thread.
State diagram of a Thread
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Lifecycle – Blocked state
• A thread is said to be blocked when it is prevented form entering into the runnable state and
subsequently the running state.
• This happens when the thread is sleeping, or waiting in order to satisfy certain requirements.
• A blocked thread is considered “ not runnable” but not dead and therefore fully qualified to run again.
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Lifecycle – Dead state
• A running thread ends its life when is has completed executing its run() method. It is a natural death.
• However, we can kill it by sending the stop message to it at any state thus causing a premature death
to it.
• A thread can be killed as soon it is born, or while it is running, or even when it is in “not runnable”
(blocked) condition.
New
Thread
Active
Thread
Idle Thread
(Not Runnable)
Thread Creation or Declaration of User-Defined Threads
• Thread can be declared in two ways :
1. Create a class that extends the Thread class
2. Create a class that implements the Runnable interface
1. Create a class by extending Thread 1. Create a class that implements the interface
class and override run() method: Runnable and override run() method:
2. Creating Object:
2. Create object: MyThread myObject = new MyThread();
MyThread thr1 = new MyThread(); 3. Creating Thread Object:
3. Start Execution of threads: Thread thr1 = new Thread( myObject );
thr1.start(); 4. Start Execution:
thr1.start();
Program to create a Thread – Using extends for
java.lang.Thread class
class Demo
class MyThread extends Thread
{
{
public static void main(String args[])
public void run()
{
{ //Job of thread executed by child thread //main thread creating child thread object
for(int i=0;i<10;i++) MyThread t=new MyThread();
{ //starting of thread
System.out.println(“child thread”); t.start();
} //Now there are two threads – main and child thread
}
} for(int i=0;i<10;i++)
{//Job of thread executed by main thread
System.out.println("main thread");
}
}
}
Compile and Check for sequence of
execution of child and main thread jobs
Program to create a Thread – Using implements
for java.lang.Runnable interface
class Demo
class MyThread1 implements Runnable
{
{
public static void main(String args[])
public void run()
{
{//Job of thread executed by child thread
//main thread creating child thread object
for(int i=0;i<5;i++)
MyThread1 t1=new MyThread1();
{
Thread obj1=new Thread(t1);
System.out.println("child thread "+i);
//starting of thread
}
obj1.start();
} //Now there are two threads – main and child thread
}
for(int i=0;i<5;i++)
{//Job of thread executed by main thread
System.out.println(“main thread "+i);
}
}
Compile and Check for sequence of }
execution of child and main thread jobs
Difference between extends Thread class and implements Runnable
• The limitation with "extends Thread" approach is that if you extend Thread, you
can not extend anything else. Java does not support multiple inheritance. In
reality, you do not need Thread class behavior, because in order to use a thread
you need to instantiate one anyway.
• On the other hand, Implementing the Runnable interface gives you the choice to
extend any class you like, but still define behavior that will be run by separate
thread.
• Another difference between Thread and Runnable comes from the fact that you
are extending Thread class just for run() method but you will get overhead of all
other methods which come from Thread class. So, if your goal is to just write
some code in run() method for parallel execution then use Runnable instead of
extending Thread class.
• When you extends Thread class, each of your thread creates unique object and
associate with it.
• When you implements Runnable, you can save a space for your class to extend
any other class in future or now.
Thread Methods - predefined
• currentThread() - This method return complete information about the
current thread like it return name of current thread, name of group of
current thread, priority number of current thread.
• start()
• run()
• stop()
• getName() - It is a sub method of current thread method and it return
name of current thread.
• setName() - It is a child method of current thread method and it is use to
set name of current thread.
• sleep() - This method is used to block the current thread until the given
sleep time is not complete.
• getpriority() - It is a child method of current thread and this method
return the priority number of the current thread.
• setpriority() - It is a child method of current thread method and this
method is used to set the priority number of current thread.
• wait()
• join()
• isAlive()
Thread methods – currentThread()
class Demo
{
public static void main(String args[])
{
System.out.println("current thread information is");
System.out.println(Thread.currentThread());
}
}
Thread methods – getName()
class Demo
{
public static void main(String args[])
{
System.out.println("name of current thread ");
System.out.println(Thread.currentThread().getName());
}
}
output
name of current thread
main
Thread methods – setName()
class Demo
{
public static void main(String args[])
{
Thread.currentThread().setName("Parent");
System.out.println("name of current thread ");
System.out.println(Thread.currentThread().getName());
}
} output
name of current thread
Parent
Thread methods – getPriority()
class Demo
{
public static void main(String args[])
{
System.out.println("current thread priority ");
System.out.println(Thread.currentThread().getPriority());
}
}
Output
current thread priority
5
Thread methods – setPriority()
class Demo
{
public static void main(String args[])
{
Thread.currentThread().setPriority(9);
System.out.println("current thread priority ");
System.out.println(Thread.currentThread().getPriority());
}
} Output
current thread priority
9
Thread methods – sleep()
class Demo
{
public static void main(String args[])
{
int i;
for(i=1;i<=5;i++)
{
System.out.println(i);
try Output
{ 1
Thread.sleep(2000); //2 sec// 2
} 3
catch(Exception e) 4
{ 5
}
}
}
}
Thread methods – stop()
class Thread1 extends Thread class Thread2 extends Thread class Demo
{ { {
public void run() public void run() public static void
{ { main(String args[])
for(int i=0;i<5;i++) for(int j=0;j<5;j++) {
Thread1 t1=new Thread1();
{ { Thread2 t2=new Thread2();
if(i==2) if(j==3) t1.start();
stop(); stop(); t2.start();
System.out.println("Thread1:"+i); System.out.println("Thread 2:"+j);
}
} }
} } }
} }
output
Thread 1:0
Thread 1:1
Thread 2:0
Thread 2:1
Thread 2:2
Thread methods – yield()
yield() method causes to pause current executing thread for giving a chance to remaining
waiting threads of same priority.
If there are no waiting threads or all waiting threads have low priority then the same thread will
continue its execution once again.
class Thread1 extends Thread class Thread2 extends Thread class Demo
{ { {
public void run() public void run() public static void
{ { main(String args[])
for(int i=0;i<5;i++) for(int j=0;j<5;j++) {
Thread1 t1=new Thread1();
{ { Thread2 t2=new Thread2();
if(i==2) if(j==3) t1.start();
yield(); yield(); t2.start();
System.out.println("Thread1:"+i); System.out.println("Thread 2:"+j);
}
} } Output
Thread 1:0
System.out.println("Exit from System.out.println("Exit from } Thread 1:1
thread1"); thread2"); Thread 2:0
Thread 2:1
} } Thread 2:2
Thread 2:3
Thread 2:4
} } Exit from thread2
Thread 1:2
Thread 1:3
Thread 1:4
Exit from thread1
Thread methods – isAlive()
isAlive() method tests if the thread is alive or not and it return boolean value.
output
new status :true
status :true
status :true
status :true
status :true
status :true
Thread methods – join() output
MyThread :0
If a thread wants to wait until completing some other thread then we MyThread :1
should go for join MyThread :2
MyThread :3
method. For example, if a thread t1 wants to wait until completing t2 MyThread :4
then “t1 has to call t2.join()”. Exit from my thread
Main Thread :0
If t1 executes t2.join() then immediately t1 will enter into waiting Main Thread :1
state until t2 completes. Once t2 completes then t1 will continue its Main Thread :2
Main Thread :3
execution. class Demo Main Thread :4
Exit from main thread
{
public static void main(String args[])
class MyThread extends Thread {
{ MyThread t1=new MyThread();
public void run() t1.start();
{ for(int j=0;j<5;j++)
for(int i=0;i<5;i++) {
{ try { t1.join(); }
System.out.println("MyThread :"+i); catch(Exception e) { }
} }
System.out.println("Exit from my System.out.println("Exit from main thread");
thread");
}
}
} }
Thread methods – synchronized(this)
• Synchronization in java is the capability of control the
access of multiple threads to any shared resource.
• Why we use :
1. To prevent thread interference.
2. To prevent consistency problem.
• wait(), notify() and notifyAll() method are present in object class but not in
thread class.
• wait(), notify() and notifyAll() method are called from synchronized area
otherwise we get run time exception error saying “illegal moniter state
exception”
• wait(), notify() and notifyAll() methods are only method which release the lock.
• Note:
▫ Every wait method throws interrupted exception which is checked exception hence
whenever we are using wait method compulsory we should handle these interrupted
exception either by try, catch or by throws keyword otherwise we will get compile time
error
Difference between notify() and notifyAll()
• We can use notify() method to give notification for only
one waiting thread if multiple threads are waiting then
only one thread will be notify and remaining thread will
have to wait for further notification.
Object.notify(), or
Object.notifyAll()
Sleeping
Object.wait()
Ready-to-run
start()
stop(), Running
or run()
exits
Data
received or
Dead Lock
obtained
Blocked
Differences between Process and Thread
Process Thread
• Process can be divided into • Threads cannot be sub
multiple threads divided.
• Each process has its own • Threads of the same process
memory space share a common memory
• It is difficult to create a space.
process • It is easy to create a thread
Producer consumer problem
• Producer thread is responsible to produce items to the queue and consumer
thread is responsible is responsible to consume items to the queue.
• If queue is empty then consumer thread will call wait method and enter into
waiting state.
• After producing items to the queue producer thread is responsible to call notify
method then waiting consumer will get notification and continue its execution
with updated items.
CONSOLE
if (number2 != 0)
System.out.println(number1 + " / " + number2 + " is " +
(number1 / number2));
else
System.out.println("Divisor cannot be zero ");
}
}
CONSOLE
try {
double result = number1 / number2;
}
catch (Exception ex) {
System.out.println( "Exception: an integer cannot be divided by zero ");
}
CONSOLE
Enter two integers: 100 0
Exception: an integer cannot be divided by zero
Execution continues ...
Exception Handling Advantages
Exception handling separates error-handling code from normal programming
tasks, consequently making programs easier to read and to modify.
Business logic
(this is what needs to be done)
try {
if (number2 == 0) Your turn
throw new ArithmeticException("Divisor cannot be zero"); 1. Replace with
Exception(…)
System.out.println(number1 + " / " + number2 + " is " + 2. What if the try-
(number1 / number2)); catch statement
} is not used?
catch (Exception ex) { 3. Use
System.out.println( "Exception: an integer " + ex.getMessage()
"cannot be divided by zero ");
}
System.out.println("Execution continues ...");
} CONSOLE
} Enter two integers: 100 0
Exception: an integer cannot be divided by zero
Execution continues ...
Java Exception Handling
• Java developers have identified most possible situations that are capable of
terminating a program abruptly and represented them as a hierarchy of classes
handled by java.lang.Throwble.
• When the exception occurs in a method, the process of creating the exception
object and handing it over to runtime environment is called “throwing the
exception”.
• Once runtime receives the exception object, it tries to find the handler for the
exception. Exception Handler is the block of code that can process the exception
object.
• The logic to find the exception handler is simple – starting the search in the
method where error occurred, if no appropriate handler found, then move to the
caller method and so on.
Exception Handling Overview – two categories of Exceptions
Property Checked Exception Unchecked Exception
Also known as checked exceptions are known to unchecked exceptions are not known
compiler i.e they are the exceptions to compiler. They are the exceptions
that are checked at compile time and that are not checked at compile time,
are known as compileTime because they occur only at run time.
exceptions in java. That’s why these exceptions are also
known as runtime exceptions in java.
Should be solved Checked exceptions are those which Unchecked exceptions are those which
at compile or need to be taken care at compile need to be taken care at runtime in java.
runtime? time in java.
Benefit/ We cannot proceed until we fix Whenever runtime exception occurs
Advantage compilation issues which are most execution of program is interrupted, but
likely to happen in program, this by handling these kind of exception we
helps us in avoiding runtime avoid such interruptions and end up
problems upto lot of extent in java. giving some meaningful message to
user in java.
Exception For propagating checked unchecked exceptions are
propagation exceptions method must throw automatically propagated in java.
exception by using throws keyword.
Most frequently faced SQLException, NullPointerException,
exceptions IOException, ArithmeticException ArrayIndexOutOfBoundsException.
ClassNotFoundException
Java Exception Handling – Class Hierarchy of Exceptions
• And catch that exception object and transfer the control along with
the identified exception object to the catch block by suspending the
execution of the try block.
finally
{
//This is the finally block.
}
Java Exception Handling Throwable class - Methods with Description
1 public String getMessage()
Returns a detailed message about the exception that has occurred. This message is initialized
in the Throwable constructor.
try
{
int i = 10/0; //This statement throws ArithmeticException
finally
{ System.out.println("This block is always executed"); }
for (int i = 0; i < 6; i++) After executing respective catch block, this statement will
After executing respective catch block, this statement will
be executed
be executed
{
NullPointerException will be caught here
After executing respective catch block, this statement will be executed
NumberFormatException will be caught here
be executed
catch(NumberFormatException ex)
{ System.out.println("NumberFormatException will be caught here"); }
catch(Exception ex)
{
System.out.println("This block handles all types of exceptions");
}
}
} Output
This block handles all types of exceptions
This block handles all types of exceptions
This block handles all types of exceptions
} This block handles all types of exceptions
This block handles all types of exceptions
Java Exception Handling Keywords – try, catch, finally block example 7
Note: The order of catch blocks should be from most
public class ExceptionHandling specific to most general ones. i.e Sub classes of
{ Exception must come first and super classes later. If
you keep the super classes first and sub classes later,
public static void main(String[] args)
you will get compile time error : Unreachable Catch
{ Block.
try
{
int i = Integer.parseInt("abc"); //This statement throws NumberFormatException
}
catch(Exception ex)
{ System.out.println("This block handles all exception types"); }
catch(NumberFormatException ex)
{
//Compile time error
//This block becomes unreachable as
//exception is already handled by above catch block
}
} Output
ExceptionHandling.java:15: error: exception NumberFormatException has already been caught
} catch(NumberFormatException ex)
^
Java Exception Handling Keywords – try, catch, finally block example 8
correct form of ex 7
public class ExceptionHandling Note: The order of catch blocks should be from most
{ specific to most general ones. i.e Sub classes of
public static void main(String[] args) Exception must come first and super classes later. If
{ you keep the super classes first and sub classes later,
try you will get compile time error : Unreachable Catch
{ Block.
int i = Integer.parseInt("abc"); //This statement throws NumberFormatException
}
catch(NumberFormatException ex)
{
System.out.println("This block handles NumberFormatException");
}
catch(Exception ex)
{
System.out.println("This block handles all exception types");
}
▫ Such explicitly thrown exception must be handled some where in the program,
otherwise program will be terminated.
• Rethrowing an exception:
▫ Exceptions occurred in the try block are caught in catch block. Thus caught
exceptions can be re-thrown using throw keyword.
} Output
NullPointerException thrown by methodWithThrows() method will be caught here
Java Exception Handling - throws keyword example 15
public class ExceptionHandling Note: The main use of throws keyword in java is that an exception
can be propagated through method calls.
{
static void methodOne() throws NumberFormatException
{
int i = Integer.parseInt(“abc”); //This statement throws NumberFormatException
}
For example,
java.sql package has all classes needed for database operation.
java.io package has classes related to input-output operation.
package com;
class A
{
//Some statements
}
//package com; If you declare here, it gives compile time error
Conventions for Naming Java Packages
• Only alphabets, numbers and an underscore are allowed
in naming the packages.