05 - Multithreading in Java
05 - Multithreading in Java
Multitasking Introduction
The process of executing several tasks simultaneously is called ‘Multitasking‘. There are 2 types of
multitasking.
1) Process based Multitasking.
2) Thread based Multitasking.
1) Process based Multitasking: Executing several tasks simultaneously where each task is a separate
independent process is called ‘Process based Multitasking‘.
Example: While writing a java program in the editor, we can run MP3 player. At the same time we can
download a file from the net. All these tasks are executing simultaneously and independent of each
other. Hence it is process based Multitasking.
Example: assume there is code of 10000 lines, now we can divide this program into two
thread for 5000 lines of independent code. Due to which exception time is reduced &
performance improved.
What is a 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 (it contains run() method
with empty implementation).
Under preemptive scheduling, the highest priority task executes until it enters the waiting or
dead states or a higher priority task comes into existence. Under time slicing, a task executes
for a predefined slice of time and then reenters the pool of ready tasks. The scheduler then
determines which task should execute next, based on priority and other factors.
Difference bw t.start() & t.run
Therefore in the case of t.start() a new thread will be created which is responsible for the
excecution of run method. Therefore t.start() is responsible for creating thread.
Case 1: Here we are not defining run() method for thread Case 2: Here run() method without argument is
which is job of it. Even though if we are not defining run() called because its overridden from Thread class.
method, in this case compiler will call run() method of Thread So to call run(int i) we have explicitly call it by
class which has empty implementation & output for this method call i.e. t.run(3).
program also be empty i.e. blank.
Three possibilities of o/p for this programs as stated above, coz thread is created therefore no guaranty of output order.
2) Java Thread Example by implementing Runnable interface
If you are not extending the Thread class, your class object would not be treated as a thread
object. So you need to explicitly create Thread class object. We are passing the object of your
class that implements Runnable so that your class run() method may execute.
May be in Thread(Runnable r) code is something like below
Thread(Runnable r)
{
r.run();
….
}
Which way is better?
Ans: Implementing Runnable interface because Extending Thread class will not give you an
option to extend any other class. But if you implement Runnable interface you could extend
other classes in your class.
So depending on your design requirement you could use either of the methods.
NAMING THREAD AND CURRENT THREAD
Naming Thread
The Thread class provides methods to change and get the name of a thread. By default, each
thread has a name i.e. thread-0, thread-1 and so on. By we can change the name of the thread
by using setName() method. The syntax of setName() and getName() methods are given
below:
Possibility 1
Possibility 2
Current Thread
1. New
2. Runnable
3. Running
4. Non-Runnable (Blocked)
5. Terminated
1) New: The thread is in new state if you create an instance of Thread class but before the
invocation of start() method.
2) Runnable: The thread is in runnable state after invocation of start() method, but the thread
scheduler has not selected it to be the running thread.
3) Running: The thread is in running state if the thread scheduler has selected it.
4) Non-Runnable (Blocked): This is the state when the thread is still alive, but is currently
not eligible to run.
5) Terminated: A thread is in terminated or dead state when its run() method exits.
Thread Class Methods
1) yield():
yield() method pauses the currently executing thread temporarily for giving a chance
to the remaining waiting threads of the same priority to execute.
If there is no waiting thread or all the waiting threads have a lower priority then the
same thread will continue its execution.
The yielded thread when it will get the chance for execution is decided by the thread
scheduler whose behavior is vendor dependent.
It can only make a thread from Running State to Runnable State, not in wait or blocked
state.
Syntax of sleep() method in java:The Thread class provides two methods for sleeping a
thread:
Note: while its sleeping there is chance the thread may get interrupted therefore we have to throw InterruptedException
Interrupting a Thread:
The isInterrupted() method returns the interrupted flag either true or false.
The static interrupted() method returns the interrupted flag after that it sets the flag to false if it is
true.
Note:
Whenever we are calling interrupt() method we may not see the effect immediately, if
the target Thread is in sleeping or waiting state it will be interrupted immediately.
If the target Thread is not in sleeping or waiting state then interrupt call will wait until
target Thread will enter into sleeping or waiting state. Once target Thread entered into
sleeping or waiting state it will effect immediately.
In its lifetime if the target Thread never entered into sleeping or waiting state then there
is no impact of interrupt call simply interrupt call will be wasted.
2) Join(): If a Thread wants to wait until
completing some other Thread then we should go
for join() method.
Example1: If a Thread t1 executes t2.join() then t1
should go for waiting state until completing t2.
1) public final void join(): This java thread join method puts the current thread on wait until
the thread on which it’s called is dead. If the thread is interrupted, it throws
InterruptedException.
2) public final void join(long millis): This java thread join method is used to wait for the
thread on which it’s called to be dead or wait for specified milliseconds. Since thread execution
depends on OS implementation, it doesn’t guarantee that the current thread will wait only for
given time.
3) public final synchronized void join(long millis, int nanos): This java thread join method
is used to wait for thread to die for given milliseconds plus nanoseconds.
Here, main Thread will wait until completing child Here, main Thread will wait until 2 sec for child Thread.
Thread. in this the output is sita Thread 5 times followed Else will continue execution
by Rama Thread 5 times.
Waiting of child Thread until completing main
Thread
Eg-2 in this E.g. both has joint account and at a same time both are performing
transactions. If wife succeeded to withdraw 450 then hubby is confused why
he is not able withdraw even bal is 500 Rs/-
So there is a need to synchronize the action of multiple threads and make sure that only
one thread can access the resource at a given point in time.
Synchronization
1) Synchronization in java is the capability to control the access of multiple threads to any
shared resource.
2) Java Synchronization is better option where we want to allow only one thread to
access the shared resource.
3) Synchronized is the keyword applicable for methods and blocks but not for classes
and variables.
4) If a method or block declared as the synchronized then at a time only one Thread is
allow to execute that method or block on the given object.
5) The main advantage of synchronized keyword is we can resolve date inconsistency
problems.
6) But the main disadvantage of synchronized keyword is it increases waiting time of the
Thread and effects performance of the system. Hence if there is no specific
requirement then never recommended to use synchronized keyword.
7) While a Thread executing any synchronized method the remaining Threads are not
allowed execute any synchronized method on that object simultaneously. But
remaining Threads are allowed to execute any non-synchronized method
simultaneously. [Lock concept is implemented based on object but not based on
method].
Concept of Lock in Java
1) Every object in java has a unique lock. Whenever we are using synchronized keyword
then only lock concept will come into the picture.
2) If a Thread wants to execute any synchronized method on the given object 1st it has
to get the lock of that object. Once a Thread got the lock of that object then it's allow
to execute any synchronized method on that object. If the synchronized method
execution completes then automatically Thread releases lock.
When to use Synchronization & non-Synchronization?
Thread Synchronization: There are two types of thread synchronization mutual exclusive
and inter-thread communication.
1) Mutual Exclusive
Synchronized method.
Synchronized block.
Static synchronization.
2) Cooperation (Inter-thread communication in java)
1) Mutual Exclusive: Mutual Exclusive keep threads from interfering with one another while
sharing data. This can be done by three ways in java:
a) by synchronized method
b) by synchronized block
c) by static synchronization
a) Java synchronized method:
If a method or block declared as the synchronized then at a time only one Thread is
allow to execute that method or block on the given object.
When a thread invokes a synchronized method, it automatically acquires the lock for
that object and releases it when the thread completes its task.
In below E.g. we are calling Wish method of Display class from multiple threads having same object.
!) If we are not declaring wish() method as synchronized then both Threads will be executed simultaneously and we will get
irregular output.
2) If we declare wish() method as synchronized then the Threads will be executed one by one that is until completing the 1st
Thread the 2nd Thread will wait
Note: Here as t1 has lock of d object, so until it unlocks this lock t2 can’t access sync method.
Even though we declared wish() method as synchronized but we will get irregular
output in this case, because both Threads are operating on different objects. Here
t1 having lock of d1 & t2 having lock of d2 so both are allow in sync method.
b) Static synchronization: If you make any static method as synchronized, the lock will be
on the class not on object.
From right side image shows class X with six thread object & their accessibility on class x methods. T1 can access m1(), but t2 & t3 can’t access m1() & m2()
respectively as t1 holds class lock. T4, t5, t6 can access m3, m4 & m5 methods respectively as those don’t require class lock, and they requires object lock.
c) Synchronized block in java
1. If very few lines of the code required synchronization then it's never recommended to
declare entire method as synchronized we have to enclose those few lines of the code
with in synchronized block.
2. The main advantage of synchronized block over synchronized method is it reduces
waiting time of Thread and improves performance of the system.
2) Synchronized(b){}: To get the lock of a particular object 'b' we have to declare this
synchronized block. If thread got lock of 'b' object then only it is allowed to execute this
block.
In above e.g. to get lock of current object we used Synchronized(this){}. Here first t1 gets
lock of object d & lock this object, t2 has to wait for t1 to release lock. Hence sync is done.
Case study case 1: if created multiple objects then it won’t work see e.g. below.
Here we are using both different object when t1.start() runs then t1 locks object d1, & when
t2.start() runs then t2 locks d2 object, here both thread locks different object hence Sync is
not performed coz no one has to wait for releasing lock. to overcome this problem use
Synchronized(Display.class){} which has class level lock.
E.g. using Synchronized(Display.class){}
FAQ
1) What is Race condition?
Ans: If multiple threads are operating simultaneously on same java object then there may be
a chance of data inconsistency problem, this is called Race Condition. We can overcome this
problem by using Synchronized keyword.
2) While a Thread executing a synchronized method on the given object is the remaining Threads
are allowed to execute other synchronized methods simultaneously on the same object?
Ans: No.
3) Is a Thread can hold more than one lock at a time?
Ans: Yes, up course from different objects. Example:
Here t1 has two locks i.e. lock first it will have lock of x then lock of y.
4) What is synchronized statement?
Ans: The statements which present inside synchronized method and synchronized block are
called synchronized statements. [Interview people created terminology].
Inter-thread communication in Java (performs only in synchronized area )
Inter-thread communication or Co-operation is all about allowing synchronized threads
to communicate with each other.
Two Threads can communicate with each other by using wait(), notify() and notifyAll()
methods.
These methods have been implemented as final methods in Object
class, so they are available in all the classes. All three methods can
be called only from within a synchronized context.
All the three methods are listed below
Here while executing wait() method any thread can interrupt waiting tread that’s why it throws
IE exception.
Right side is e.g. how we can access wait(),
notify() and notifyAll() methods from object class
to our program.
O/P
Causes current thread to release the lock and wait until either another thread invokes
the notify() method or the notifyAll() method for this object, or a specified amount of
time has elapsed.
The current thread must own this object's monitor, so it must be called from the
synchronized method only otherwise it will throw exception.
Wakes up a single thread that is waiting on this object's monitor. If Wakes up all threads that are waiting on this
any threads are waiting on this object, one of them is chosen to be object's monitor.
awakened. The choice is arbitrary and occurs at the discretion of
the implementation. Syntax: public final void notifyAll()
Syntax: public final void notify()
Why wait(), notify() and notifyAll() methods are defined in Object class not Thread class?
Ans:-It is because they are related to lock and object has a lock.
Is Thread
Except these (wait(),notify(),notifyAll()) methods there is no other place(method) Method
Releases Lock?
where the lock release will be happen.
yield() No
join() No
sleep() No
Once a Thread calls wait(), notify(), notifyAll() methods on any object then it wait() Yes
releases the lock of that particular object but not all locks it has. notify() Yes
notifyAll() Yes
Case 2: using sleep() method for 10 sec, in this case we’ll get expected o/p but unnecessarily our main thread has to wait for 9 sec
coz child thread completes its calculation within Nano seconds..
Case 3: using join() Method here also we’ll get expected result, but what if there is 1 crore line of code is there below for loop.
Then here also main thread has to wait to complete those 1 crore lines of code. So join() is not recommended.
Case 4: If you are waiting for updation then it is recommended to call wait() & notify() method. Note: wait() notify() works only in
synchronized area. Hence declared in sync blocks.
Case 4:
If 2 Threads are waiting for each other forever (without end) such type of situation (infinite
waiting) is called dead lock.
Deadlock can occur in a situation when a thread is waiting
for an object lock, that is acquired by another thread and
second thread is waiting for an object lock that is acquired
by first thread. Since, both threads are waiting for each
other to release the lock, the condition is called deadlock.
There are no resolution techniques for dead lock but several prevention (avoidance)
techniques are possible.
Synchronized keyword is the cause for deadlock hence whenever we are
using synchronized keyword we have to take special care.
In the side e.g.
If thread "A" calls methodA and thread "B" calls methodB, then: lockA
will be aquired from threadA and lockB from threadB.
Then threadA will have to wait for lockB while threadB waits for lockA
from the recently blocked threadA.
This is because the objects are locked in different order. This is one of the
most common reasons of deadlocks, so if you want to avoid them, be sure that
the locks are acquired in order. Consider below e.g.
If method1() and method2() both will be called by two or Now there would not be any deadlock because both
many threads , there is a good chance of deadlock because if methods are accessing lock on Integer and String class
thread 1 acquires lock on Sting object while executing literal in same order. So, if thread A acquires lock on Integer
method1() and thread 2 acquires lock on Integer object while object , thread B will not proceed until thread A releases
executing method2() both will be waiting for each other to Integer lock, same way thread A will not be blocked even if
release lock on Integer and String to proceed further which will thread B holds String lock because now thread B will not
never happen. expect thread A to release Integer lock to proceed further.
Daemon Thread in Java
The Threads which are executing in the background are called daemon Threads.
The main objective of daemon Threads is to provide support for non-daemon Threads
like main Thread.
Example:
Garbage collector thread
Whenever the program runs with low memory the JVM will execute Garbage Collector to
provide free memory. So that the main Thread can continue its execution.
We can check whether the Thread is daemon or not by using isDaemon() method of
Thread class.
public final boolean isDaemon();
We can change daemon nature of a Thread by using setDaemon () method.
public final void setDaemon(boolean b);
But we can change daemon nature before starting Thread only. That is after starting
the Thread if we are trying to change the daemon nature we will get R.E saying
IllegalThreadStateException.
Default Nature: Main Thread is always non daemon and we can't change its
daemon nature because it's already started at the beginning only.
Main Thread is always non daemon and for the remaining Threads daemon nature
will be inheriting from parent to child that is if the parent is daemon child is also
daemon and if the parent is non daemon then child is also non daemon.
Whenever the last non daemon Thread terminates automatically all daemon Threads
will be terminated.
The sole purpose of the daemon thread is that it provides services to user thread for
background supporting task. If there is no user thread, why should JVM keep running this
thread. That is why JVM terminates the daemon thread if there is no user thread.
Deadlock vs Starvation
A low priority Thread has to wait until completing all high priority Threads (Suppose there are
1 crore of threads out of only one is having priority 1 rest all have max priority i.e. 10 ). This
long waiting of Thread which ends at certain point is called starvation.
GreenThread: The threads which are managed completely by JVM without taking support
for underlying OS, such type of threads are called Green Threads.