Multi Threading
Multi Threading
• Thread based:
where each task is a part of same program
(program level)
Applications
• To develop multimedia graphics
• To develop animations
New / t.start()
Born Ready/
Running
Runnable If Thread
Scheduler
If run d
meth etes
comp
allocate
processors
()
o
l
Dead
Some important points
When a thread is started once it can’t be restarted
again. If we will try to restart then exception will be
raised saying…
…IllegalThreadStateException
It’s an run time exception
public static void main(String args[])
{
Thread t=new Thread();
t.start();
t.start();//Here exception will be raised
}
We can define a thread by implementing
Runnable interface
Runnable interface doesn’t contain start()
method. It contains only run() method.
--------------------------------------------
class MyRunnable implements Runnable{
public void run(){
for( int i=0;i<10;i++)
System.out.println(“Child Thread”);
}
} Job of the thread
Executed by child
thread
class ThreadDemo{
public static void main(String args[]){
MyRunnable r=new MyRunnable();
Thread t=new Thread(r);
t.start();
for(int i=0;i<10;i++)
System.out.println(“main thread”);
}
}
Output: we will get mixed output …means n
number of outputs are possible
class ThreadDemo{
public static void main(String args[]){
MyRunnable r=new MyRunnable();
Thread t1=new Thread();
Thread t2=new Thread(r);
}
}
Case study
----------------------------
1. t1.start();
A new thread will be created and which is
responsible for execution of thread class run()
method which has empty implementation
2. t1.run();
no new thread will be created and thread
class run() method will be executed just like
normal method call.
3. t2.start();
A new thread will be created which is
responsible for execution of MyRunnable run()
method.
4. t2.run();
no new thread will be created and
MyRunnable run() method will be executed just
like normal method call.
5. r.start();
We will get compile time error because
Runnable interface doesn’t have start() method
6. r.run();
MyRunnable run() method will be
executed like normal method call and no new
thread will be created.
}
Class Test{
public static void main(String args[]){
System.out.println(“name of current
thread:”+Thread.currentThread().getName());
MyThread t=new MyThread();
System.out.println(“name of child thread:”+t.getName());
Thread.currentThread().setName( “cse”);
System.out.println(“now name of current
thread:”+Thread.currentThread().getName());
}
}
Output : name of current thread : main
name of child thread : Thread-0
now name of child thread : cse
Thread Priorities
• Every thread in java has some priority either
provided by programmer or JVM.
• Priority range is 1 to 10.
• Thread Scheduler will use priorities while
allocating processor.
• Thread with highest priority will get chance first
to execute
• If priorities are same then we can’t expect that
which thread will get chance first.
• The default priority for main thread is 5 but
for all remaining threads default priority will
be inherited from parent thread to child
thread.
• These are the methods to get and set priority
of a thread
public final int getPriority();
public final void setPriority(int p);
• Some predefined constants for priority
1. Thread.MIN_PRIORITY for 1
2. Thread.MAX_PRIORITY for 10
3. Thread.NORM_PRIORITY for 5
Sample program for Priority Demo
public static void main(String args[]){
System.out.println(“current thread priority:”+
Thread.currentThread().getPriority());// 5
Thread.currentThread().setPriority(12); //runtime
exception
Thread.currentThread().setPriority(7);
MyThread t=new MyThread();
t.start();
System.out.println(“current thread priority:”+
t.getPriority());// 7
}
Thread main
class Thread
e ad
ss
thr
c l a
nt
nt
e
Pare
Par
MyThread t=new
MyThread();
Example on Priority
class Mythread extends Thread{
public void run(){
for( int i=0;i<10;i++){
System.out.println(“Child Thread”);
}
}
}
class ThreadPriorityDemo{
public static void main(String args[]){
MyThread t=new MyThread();
t.setPriority(10);
t.start();
for( int i=0;i<10;i++)
System.out.println(“Parent Thread”);
}
}
Output: In this program output should be only one
Note:
In the previous program at some system output
may vary for each execution because some
systems don’t follow priority order
Preventing Thread execution temporarily
• Methods
1. yield();
2. join();
3. sleep();
1. yield() method
• This method causes to pause the current
executing thread to give the chance to other
waiting thread of same priority. If there is no
waiting thread or all the waiting threads
having low priority then same thread can
continue its execution.
• If multiple threads are waiting with same
priority then which thread will get chance , it
depends on thread scheduler
• The thread which is yielded ,when again it will get
chance ,it depends on thread scheduler
public static native void yield();
Sample program
-----------------
Class MyThread extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println(“child thread”);
Thread.yield();
}
} Line 1
class ThreadYieldDemo{
public static void main(String args[]){
MyThread t=new MyThread();
t.start();
for(int i=0;i<10;i++){
System.out.println(“parent thread”);
}
}
}
In this program if we comment Line 1 then the both threads
will be executed simultaneously and we can’t expect that
which thread will complete its execution first else child
thread always calls yield() method so main thread will get
more chance .Hence chance of completion of main thread is
more than child thread
Impact of yield() method on life cycle of a
Thread
MyThread t=new MyThread(); Thread.yield();
New / t.start();
Born Ready/
Running
Runnable
If Thread
If run d
meth etes
comp
Scheduler
allocate
()
o
l
processors
Dead
2. join() method
• If thread wants to wait until completing some
other thread then we can go for join()
method. For example a thread t1 wants to
wait until completing the execution of thread
t2 then t1 has to call t2.join();
eg.
Venue fixing Wedding card Wedding card
activity(t1) printing(t2) distribution(t3)
t2 t2
t1
t1.join(); t2.join();
In the above example t2 has to wait until
venue fixing thread t1 completion, hence t2 has
to call t1.join() method.
Wedding card distribution thread t3 has to
wait until completion of wedding card printing,
hence t3 has to call t2.join() method.
public final join();
public final join(long ms );
public final join(long ms , int ns);
• Every join() method throws
InterruptedException that is checked
Exception hence compulsory to handle
An example for join() method
class MyThread extends Thread{
public void run(){
for( int i=0;i<10;i++){
System.out.println(“child thread”);
try{
Thread.sleep(1000);
}
catch(InterruptedException e){}
}
}
}
class ThreadJoinDemo {
public static void main(String args[]){
MyThread t=new MyThread();
t.start();
t.join();
Line 1
//t.join(2000);
//t.join(2000,80);
for(int i=0;i<10;i++)
System.out.println(“child thread”);
}
}
//here main thread will wait until completion of child
thread
If we comment Line 1 then both main
and child thread will be executed simultaneously
and we can’t except exact output.
If run d
meth etes
comp
t e s or ted
l e rup
omp ires or ot inter
()
c
o
2
If t e exp ead g
l
ti m th r ( ) ; 00); 00);
If i ti ng o in (10 0,1
a j
If w t2. .join (200
Waiting state T2 .join
T2 Dead
(Blocked for joining)
Another example
class MyThread extends Thread{
static Thread mainThread;
public void run(){
try{
mainThread.join();
}
catch(InterruptedException e){}
for(int i=0;i<10;i++)
System.out.println(“child thread”)
}
}
class ThreadJoinDemo1{
public static void main(String args[]) throws
InterruptedException {
MyThread.mainThread = Thread.currentThread();
MyThread t=new MyThread();
t.start();
for(int i=0;i<10;i++){
System.out.println(“main thread”);
Thread.sleep(2000);
}
}
}
In this example child thread calls join() method on main thread,
hence child thread has to wait until completion of main thread
Important point regarding join() method
m3
2 ()
()
Wa t3 m
iti
sta ng
te t4
This thread will
not go in
waiting state
Non-
Synchr
synchr
onized
onized
area
area
Object
} -----------------------------------------------------------
m1()
t2 X t1 cl(x)
sta ng
iti
te
Wa
m5
2 ()
()
t3 m
m3 ( )
m4
Wa
iti
t6
()
sta ng
te
t5
t4 This thread will
not go in waiting
state
While a thread executing static synchronized
method , the remaining threads are not allowed
to execute any static synchronized method of
that class simultaneously. But remaining threads
are allowed to execute the following methods
simultaneously.
1. normal static methods.
2. synchronized instance methods.
3. normal instance methods.
Example
class Display {
public void displayn(){
for(int i=1;i<=10;i++){
System.out.println(i);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(name);
}
}
}
class MyThread1 extends Thread{
Display d;
Mythread1(Display d){
this.d=d;
}
public void run(){
d.displayn();
}
}
class MyThread2 extends Thread{
Display d;
Mythread2(Display d){
this.d=d;
}
public void run(){
d.displayc();
}
}
class SynchronizedDemo {
public static void main(String args[]){
Display d=new Display();
MyThread1 t1=new MyThread1(d);
MyThread2 t2=new MyThread2(d);
t1.start();
t2.start();
}
}
There is no fixed output . It will give mixed (irregular)
output.
If we replace displayn() and displayc() methods by…..
public synchronized void displayn(){}
public synchronized void displayc(){}
Then we will get regular output.
Synchronized block concept
• If very few lines of code requires
synchronization then it is not recommended
to declare entire method as synchronized. We
have to enclose those few lines of the code by
using synchronized block.
• The main advantage of synchronized block
over synchronized method is, it reduces
waiting time of threads and increases
performance of the system.
Declaring a synchronized block
• We can declare synchronized block as follows
1. synchronized(this){
______;
If a thread got lock of current object
______; then only it is allowed to execute
this area
}
2. synchronized( ob ){
If a thread got lock of a particular
______; object ‘ob’ then only it is allowed to
______; execute this area
}
3. synchronized( Display.class ){
If a thread got class level lock of
______; Display class then only it is allowed
______; to execute this area
}
Examples 1
class Display{
public void wish(String name){
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;// 1 lakh lines of code
synchronized(this){
for(int i=1;i<=10;i++){
System.out.print(“Hello:”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(name);
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;// 1 lakh lines of code
}
}
class MyThread extends Thread{
Display d;
String name;
MyThread(Display d, String name){
this.d=d;
this.name=name;
}
public void run(){
d.wish(name);
}
}
class SynchronizedDemo {
public static void main(String args[]){
Display d=new Display();
MyThread t1=new MyThread(d,”sir”);
MyThread t2=new MyThread(d,”ma’am”);
t1.start();
t2.start();
}
}
Here we will get regular output. If display objects
are different, then for regular output class level lock is
required.
Example 2
class Display{
public void wish(String name){
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;// 1 lakh lines of code
synchronized(Display.class){
for(int i=1;i<=10;i++){
System.out.print(“Hello:”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(name);
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;// 1 lakh lines of code
}
}
class MyThread extends Thread{
Display d;
String name;
MyThread(Display d, String name){
this.d=d;
this.name=name;
}
public void run(){
d.wish(name);
}
}
class SynchronizedDemo {
public static void main(String args[]){
Display d1=new Display();
Display d2=new Display();
MyThread t1=new MyThread(d1,”sir”);
MyThread t2=new MyThread(d2,”ma’am”);
t1.start();
t2.start();
}
}
Here also we will get regular output because we
have used class level lock.
We should know this also
• Lock concept is applicable for objects or class
but not for primitive data types.
int x=10;
synchronized(x){
__________;
__________; We will get
compile time
} error.
Can a thread acquire more than one lock
simultaneously ?
• Yes, a thread can acquire n number of locks simultaneously depending
upon conditions.
Example X x=new X();
x.m1();
class X{
public synchronized void m1(){
Y y=new Y();
Here thread has lock of X
synchronized(y){
Z z=new Z();
Here thread has lock of X,Y
synchronized(z){
_________;
_________;
}
} Here thread has lock of X,Y&Z
}
}
Inter thread communication
• Two threads can communicate each other by
using wait(), notify(), notifyAll() methods.
• The thread which expects updation is
responsible to call wait() method then
immediately thread will enter into waiting state.
• The thread which is responsible for updation,
has to call notify() method then waiting thread
will get notification and will continue its
execution with those updated items.
t1 t2
wait() notify()
----------------------------------------------
Here t1 needs updation hence it has to call wait()
method & t2 will update, hence after updating t2
has to call notify() method.
You should know this also
• wait() , notify() , notifyAll() methods are
present in class Object but not in class Thread,
because thread can call these methods on any
java objects.
t2
t1 PostBox
Stack
Queue .wait()
Student
Customer .notify()
• To call wait() , notify() , notifyAll() methods on any
object ,thread should be owner of that object i.e.
thread should have lock of that object i.e. thread
should be inside synchronized area. Hence we can call
wait() , notify(), notifyAll() methods only from
synchronized area , otherwise we will get runtime
exception ….saying IllegalMonitorStateException
• If a thread calls wait() method on any object it
immediately releases the lock of that particular object
and enters into waiting state.
• If a thread calls notify() method on any object it
releases the lock of that object but not immediately.
Except wait() , notify() , notifyAll() there is no other
method where thread releases the lock .
Impact of wait() & notify() methods on life
cycle of a Thread
MyThread t=new MyThread(); If Thread
Scheduler allocate
New / processors
t.start();
Born Ready/
Running
Runnable
If run d
meth etes
ad
comp
e
t hr
()
o
ng ock
l
ti
ai e l
;
0)
00 0);
w
If t th
10
.w it ;
t( 2 0
t2 .wa it()
0,
ai (10
go
t2 .wa
t2
Another Dead
waiting state 1. If waiting thread
to get lock got notification Waiting
2. if time expires state
3. If waiting thread
got interrupted
Example 1
class ThreadA{
public static void main(String args){
ThreadB b=new ThreadB();
b.start();
System.out.println(“sum=”+b.total);
}
}
class ThreadB{
int total=0;
public void run(){
for(int i=1;i<=100;i++)
total=total + i ;
}
}
output: Here output may come 0 or 5050 or in between 0 and 5050.
Example 2
class ThreadA{
public static void main(String args) throws InterruptedException{
ThreadB b=new ThreadB();
b.start();
Thread.sleep(2000);
System.out.println(“sum=”+b.total);
}
}
class ThreadB{
int total=0;
public void run(){
for(int i=1;i<=100;i++){
total=total + i ;
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;//1 crore lines code
}
}
Now let’s use wait() and notify methods
class ThreadA{
public static void main(String args[]){
ThreadB b=new ThreadB();
b.start();
synchronized(b){
System.out.println(“main thread trying to call
wait() method”); 1
b.wait();
4 notification”);
System.out.println(“main thread got
System.out.println(“sum=”+ b.total);
}
} 5
}
class ThreadB{
int total=0;
public void run(){
synchronized(this){
System.out.println(“child thread starts
execution”); 2
for(int i=1;i<=100;i++)
total+=i;
System.out.println(“child thread trying
to give notification”); 3
this.notify();
}
}
}
Few more facts
• Most of the time main thread gets chance to
execute.
• If child thread got chance first then if it had
given notification but main thread was
sleeping, then main thread has to sleep life
long.
Producer Consumer Problem
• Producer thread is responsible to produce items
to the queue & consumer thread is responsible
to consumes the items from queue . If queue is
empty then consumer thread calls wait() method
& enters into waiting state. After producing items
to the queue producer thread is responsible to
call notify() method. Then waiting consumer
thread will get notification and continues its
execution with updated items.
Queue q
Producer thread Consumer thread
class ConsumerThread {
class ProducerThread {
Consume(){
Produce(){
Synchronized(q){
Synchronized(q)
if( q is
{
empty)
Produce
q.wait()
item to the queue
else
q.notify()
consume items
}
}
}
}
}
}
Difference between notify() & notifyAll()
synchronized(s1){ synchronized(s1){
_____; _____;
s2.wait(); s1.wait();
_____; _____;
} }
Deadlock
• If two threads are waiting for each other
forever , such type of infinite waiting is called
deadlock.
• synchronized keyword is the only reason for
deadlock situation , hence while using
synchronized keyword , we have to take
special care.
• There are no resolution techniques for
deadlock but several prevention techniques
are available
Example
class A{
public synchronized void d1(B b){
System.out.println(“Thread1 starts execution of d1()
method”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(“Thread1 trying to call B’s last()
method”);
b.last();
}
public synchronized void last(){
System.out.println(“Inside A, this is last() method”);
}
class B{
public synchronized void d2(A a){
System.out.println(“Thread2 starts execution of d2()
method”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(“Thread2 trying to call A’s last()
method”);
a.last();
}
public synchronized void last(){
System.out.println(“Inside B, this is last() method”);
}
}
class DeadLockDemo extends Thread {
A a=new A();
B b=new B();
public void m1(){
this.start();
a.d1(b);
This line is executed
} by main thread
public void run(){ This line is executed
b.d2(a); by child thread
}
public static void main(String args[]){
DeadLock d=new Deadlock();
d.m1();
}
Deadlock v/s Starvation
• Long waiting of a thread where waiting never
ends is called deadlock.
• Long waiting of a thread where waiting ends at
certain point is called starvation.
• Example :
Low priority thread has to wait until
completion of all high priority threads. It may be
long waiting time but ends at certain point which
is nothing but starvation.
Daemon threads
• The thread which is executing in background is
called Daemon thread .
• Examples : Garbage Collector , Attach Listener,
Signal Dispatcher etc.
• The main objective of Daemon thread is to
provide supports for non daemon threads.
• For example if main thread runs with low
memory then JVM runs Garbage Collector to
destroy useless objects so that number of bytes
of free memory will be improved. With this free
memory main thread can continue its execution.
• Usually daemon threads having low priority but
based on out requirement Daemon thread can
run with high priority also.
public boolean isDaemon();
public void setDaemon( boolean b);
true Daemon
false non -Daemon
System.out.println( Thread.currentThread().isDaemon());//false
MyThread t=new MyThread();
System.out.println( t.isDaemon() );//false
t.setDaemon(true);
System.out.println( t.isDaemon() );//true
}
}
• Whenever last non-daemon thread terminates, automatically all
daemon threads will be terminated irrespective of their positions.
• Example
class MyThread extends Thread{
public void run(){
for(int i=0;i<10;i++){
System.out.println(“child thread”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
}
}
}
class DaemonThreadDemo {
public static void main(String args[]){
MyThread t=new MyThread();
t.setDaemon(true);
t.start(); Line 1
t5 t6
Thread group
• The main advantage of maintaining threads in the form of
ThreadGroup is ,we can perform common operations very easily.
main method
main thread
class Test{ main ThreadGroup
public static void main(String args[]){
System.out.println(
Thread.currentThread().getName());//main
System.out.println( Thread.currentThread().getThreadGroup().getNam
e());//main
System.out.println( Thread.currentThread().getThreadGroup().getParen
t().getName());//system
}
}
• Every thread in java belongs to some group.
main thread belongs to main group.
• Every thread group in java is the child group of
system group either directly or indirectly.
Hence System Group acts as root for all
ThreadGruops in java.
• System Group contains several system level
threads like..
1. Finalizer (Garbage Collector)
2. Reference Handler
3. Signal Dispatcher
4. Attach Listener
System
Reference Handler
main
ThreadGroup Finalizer Signal Dispatcher
Attach Listener
main thread
sub
Thread-0 ThreadGroup
t1 t2
• ThreadGroup is a java class present in
java.lang package and direct child class of
Object class.
Object
ThreadGroup
Constructors of ThreadGroup
1. ThreadGroup g=new ThreadGroup(String name);
creates a new thread group with the specified
group name. The parent of new group is the thread
group of currently executing thread.
Example ThreadGroup g=new ThreadGroup(“first”);
2. ThreadGroup g=new ThreadGroup( ThreadGroup
pg ,String name);
Example ThreadGroup g1=new ThreadGroup (g ,
“first ”);
• Example
class Test {
public static void main(String args[]) {
ThreadGroup g1=new ThreadGroup( “first
thread”);
System.out.println( g1.getParent().getName());//main
ThreadGroup g2=new ThreadGroup(g1, “second
thread”);
System.out.println( g2.getParent().getName());//
first group
}
}
Important methods of ThreadGroup class
1. String getName(); used to get name of the thread group.
2. int getMaxPriority(); used to find priority of a thread
group.
3. void setMaxPriority(int p); used to set maximum priority
of a thread group.
4. ThreadGroup getParent(); used to get parent group of
current thread group.
5. void list(); it prints information about thread group in the
console.
6. int activeCount(); returns number of active threads
present in thread group.
7. int enumerate(Thread t[]); to copy all active threads of
this thread group into provided thread array. In this case
8. int enumerate(ThreadGroup t[]); to copy all
active sub thread groups into ThreadGroup array.
9. Boolean isDaemon(); to get daemon nature of a
thread group.
10. Void setDaemon( boolean b); to change
daemon nature of a thread group.
11. Void interrupt(); to interrupt all waiting
threads of a thread group.
12. Void destroy(); to destroy thread group and its
sub thread groups.
13. Int activeGroupCount(); it returns no. of active
thread groups present in current thread group.
Example
class MyThread extends Thread {
MyThread(ThreadGroup g, String name){
super(g , name);
}
public void run(){
System.out.println(“child thread”);
try{
Thread.sleep(2000);
}
catch(InterruptedException a){}
}
}
class ThreadGroupDemo {
public static void main(String args[]) throws Exception {
ThreadGroup pg=new ThreadGroup(“parent group”);
ThreadGroup cg=new ThreadGroup(pg,“child group”);
MyThread t1=new MyThread(pg,”childthread1”);
MyThread t2=new MyThread(pg,”childthread2”);
t1.start();
t2.start();
System.out.println( pg.activeCount() );//2
System.out.println( pg.activeGroupCount() );//1
pg.list();
Thread.sleep(10000);
System.out.println( pg.activeCount() );//0
System.out.println( pg.activeGroupCount() );//1
pg.list();
}
Write a program to display all active threads
belongs to system group and its child group.
class ThreadGroupDemo {
public static void main(String args[]) {
ThreadGroup system=
Thread.currentThread().getThreadGroup().getParent();
Thread t[]=new Thread[ system.activeCount()];
system.enumerate(t);
for(Thread t1:t)
System.out.println(t1.getName()+”--- “ + t1.isDaemon());
}
}
output:
Reference Handler---true
Finalizer---true
Signal Dispatcher---true
Attach Listener---true
main----false
java.util.concurrent package
• Problems with traditional synchronized keyword
1. We are not having any flexibility to try for a lock without
waiting.
2. There is no way to specify maximum waiting time for a
thread to get lock so that thread will wait until getting
lock ,which may create performance problem ,that may
cause deadlock.
3. If a thread releases lock then which waiting thread will get
that lock ,we are not having any control on this.
4. There is no API support to list out all the waiting threads
for a lock.
5. The synchronized keyword we have to use either at
method level or within the method and it is not possible to
use across multiple methods.
• To overcome of these problems, we can go for
java.util.concurrent.locks package.
It provide several enhancements to the programmer to
provide more control on concurrency
-----------
Lock interface
• Lock object is similar to implicit lock acquired by a
thread to execute synchronized block.
• Lock implementations provide more operations
than traditional implicit locks.
Important methods of Lock interface
1. void lock();
we can use this method to acquired a lock. If lock is already available
then immediately current thread get the lock. If lock is not already
available then it will wait until getting lock. It has same behaviour as
traditional synchronized keyword.
2. boolean tryLock();
To acquired the lock without waiting.
If lock is available then thread acquires that lock and returns true. If
lock is not available then this method returns false and can continue its
execution without waiting. In this case thread will never be in waiting state.
if( l.tryLock()){
perform safe operations.
}
else{
perform alternative operations
}
3. boolean tryLock(long time , TimeUnit unit);
If lock is available then thread will get lock and continue its
execution. If lock is not available then thread will wait until
specified amount of time . Still if lock is not available then thread
can execute alternative operations.
TimeUnit: It is an enum present in java.util.concurrent package.
enum TimeUnit{
NANOSECONDS,
MRCROSECONDS,
MILLISECONDS,
SECONDS,
MINUTES,
HOURS,
DAYS;
}
e.g if(l.tryLock(1000,TimeUnit.MILLISECONDS)){
}
4. void lockInterruptibly();
acquires the lock if it is available and returns
immediately.
If the lock is not available then it will wait,
while waiting if thread will be interrupted then
then thread won’t get lock.
5. void unlock();
To call this method compulsory current
thread should be owner of the lock otherwise we
will get runtime exception saying….
IllegalMonitorStateException
Reentrantlock class
• It is implementation class of Lock interface and
direct child class of Object class.
Lock interface
Object class
ReentrantLock
ReentrantLock l=new ReentrantLock();
Reentrant means, a thread can acquire same lock
multiple times without any issue.
Internally ReentrantLock , increment thread’s
personal count when thread calls lock() method and
decrements personal count value whenever thread
calls unlock() method. All locks will be released if count
reaches to zero. false which waiting thread will
get chance ,cant expect
Constructors
-----------------------
1. ReentrantLock l=new ReentrantLock();
creates an instance of ReentrantLock.
2. ReentrantLock l=new ReentrantLock( boolean
fairness);
creates an instance of ReentrantLock withwaiting
true Longest giventhread
will get chance(FCFS)
fairness policy.
Important methods of ReentrantLock class
1. void lock();
2. boolean tryLock();
3. boolean tryLock(long time , TimeUnit unit);
4. void lockInterruptibly();
5. void unlock();
---------------------
6. int getHoldCount(); returns no. of holds of this
lock by current thread.
7. boolean isHeldByCurrentThread(); returns true
iff lock is hold by current thread.
8. int getQueueLength(); returns no. of threads
waiting for the lock.
9. Collection getQueuedThreads(); returns a
collection of threads which are waiting to get lock.
10. boolean hasQueuedThreads (); returns true if
any thread waiting to get lock.
11. boolean isLocked(); returns true if lock is
acquired by some thread.
12. boolean isFair(); returns true if fairness policy
is set with true value.
13. Thread getOwner(); returns thread which
acquired the lock.
Using ReentrantLock instead of
synchronized keyword
import java.util.concurrent.locks.*;
class Display {
ReentrantLock l=new ReentrantLock();
public void wish(String name){
l.lock();
Line 1
for(int i=0;i<10;i++){
System.out.print(“Good morning”);
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
System.out.println(name);
} Line 2
l.unlock();
}
}
class MyThread extends Thread {
Display d;
String name;
MyThread(Display d1 , String name1){
d=d1;
name=name1;
}
public void run(){
d.wish(name);
}
}
class ReentrantLockDemo {
public static void main(String args[]) {
Display d=new Display();
MyThread t1=new MyThread( d,”ravi”);
MyThread t2=new MyThread(d,”ram”);
t1.start();
t2.start();
}
}
If we comment Line 1 and Line 2 then the threads
will be executed simultaneously and we will get
irregular output else we will get regular output
Demo program for tryLock() method
import java.util.concurrent.locks.*;
class MyThread extends Thread {
static ReentrantLock l=new ReentrantLock();
MyThread(String name){
super(name);
}
public void run(){
if(l.tryLock()){
System.out.println( Thread.currentThread().getName()+”--- got lock
and performing safe operations.”);
try{
Thread.sleep(2000);
}
catch(Exception e) {}
l.unlock();
}
else {
System.out.println( Thread.currentThread().getName()+”---
unable to get lock and hence performing alternative operations.”);
}
}
}
class ReentrantLockDemo {
public static void main( String args[]) {
MyThread t1=new MyThread(“First Thread”);
MyThread t2=new MyThread(“Second Thread”);
t1.start();
t2.start();
}
}
output: First Thread ---got the got lock and performing safe operations.
Second Thread --- unable to get lock and hence performing alternative
operations.
Demo program for tryLock() method with time period
import java.util.concurrent.*;
import java.util.concurrent.locks*;
class MyThread extends Thread {
static ReentrantLock l=new ReentrantLock();
MyThread(String name){
super(name);
}
public void run(){
do{
try{
if(l.tryLock(5000,TimeUnit.MILLISECONDS)){
System.out.println( Thread.currentThread().getName()+”--- got lock.”);
Thread.sleep(30000);
l.unlock();
System.out.println( Thread.currentThread().getName()+”--- releases lock.”);
break;
}
else{
System.out.println( Thread.currentThread().getName()
+” --- unable to get lock and will try again.”);
}
}
catch(Exception e) {}
}while(true);
}
}
class ReentrantLockDemo {
public static void main(String args[]){
MyThread t1=new MyThread(“First Thread”);
MyThread t2=new MyThread(“Second Thread”);
t1.start();
t2.start();
}
}
output:
First Thread --- got lock.
Second Thread --- unable to get lock and will try again.
Second Thread --- unable to get lock and will try again.
Second Thread --- unable to get lock and will try again.
Second Thread --- unable to get lock and will try again.
Second Thread --- unable to get lock and will try again.
First Thread --- releases the lock.
Second Thread ---got lock.
Second Thread --- releases lock.
Thread Pools (Executor FrameWork)
• Creating a new thread for every job may create
performance or memory problem. To overcome
of this we should go for ThreadPools.
• Thread Pool is a pool of already created threads
, ready to do out job.
• Java 1.5 version introduced thread pool
framework to implement ThreadPool.
• ThreadPool Framework is also known as
Executor Framework.
• We can create a thread pool as follows:
ExecutorService service=
Executors.newFixedThreadPool(5);
• We can submit a Runnable job by using submit()
method.
service.submit(job);
• We can shutdown executor service by using
shutdown() method
service.shutdown();
Example
import java.util.concurrent.*;
class PrintJob implements Runnable{
String name;
PrintJob(String name1){
name=name1;
}
public void run(){
System.out.println(name+” ---Job started by
Thread:“+Thread.currentThrad().getName());
try{
Thread.sleep(5000);
}
catch(Exception e){}
System.out.println(name+” ---Job completed by
Thread:“+Thread.currentThrad().getName());
}
}
class ExecuterDemo {
public static void main(String args[]){
PrintJob jobs[]={ new PrintJob(“Asheesh”),
new PrintJob(“Rishab”),
new PrintJob(“Rahul”),
new PrintJob(“Sumanth”),
new PrintJob(“Abinash”),
new PrintJob(“Amar”)};
ExecutorService service=
Executors.newFixedThreadPool(5);
for(PrintJob job:jobs){
service.submit(job);
}
service.shutdown();
}
}
• In the above example 3 threads are
responsible to execute 6 jobs, so that a single
thread can be reused for multiple jobs.
Note : While designing web servers and
application servers, we can use ThreadPool
concept.
Default ThreadPool size is 60 for most of
the servers.
Callable & Future
• In case of Runnable job , thread won’t return
anything after completing job.
• If a thread is required to return some result after
execution then we should go for Callable interface.
Callable interface contains only one method i.e.
call().
public Object call() throws Exception
• If we submit Callable object to executer then after
completing the job, thread returns an object of the
type Future i.e. Future object can be used to
retrieve the result from Callable job.
Example
import java.util.concurrent.*;
class MyCallable implements Callable{
int num;
MyCallable (int n){
num=n;
}
public Object call() throws Exception{
System.out.println( Thread.currentThrad().getName()+” is
responsible to find sum of first ”+num+” numbers”);
int sum=0;
for(int i=1;i<=num ; i++)
sum+=i;
return sum;
}
class CallableFutureDemo {
public static void main(String args[]){
MyCallable jobs[]={ new MyCallable(10),
new MyCallable(20),
new MyCallable(30),
new MyCallable(40),
new MyCallable(50),
new MyCallable(60)};
ExecutorService service= Executors.newFixedThreadPool(5);
for(PrintJob job:jobs){
Future f=service.submit(job);
System.out.println( f.get());
}
service.shutdown();
}
}
Difference between Runnable & Callable
1. If a thread not required to return 1. If a thread required to return
anything after completing the job , some thing after completing the
then we should go for Runnable. job , then we should go for Callable.
2. Runnable interface contains only 2. Callable interface contains only
one method i.e. run(). one method i.e. call().
3. Runnable job not required to 3. Callable job required to return
return any thing so run() method is any thing so call() method’s return
void. type is Future.
4. Within the run() method if there 4. Within the call() method if there
is any chance of raising checked is any chance of raising checked
exception, compulsory we should exception, we are not required to
handle by try, catch because we handle by try, catch because call()
cannot use throws keyword. method already throws Exception.
5. Runnable interface is present in 5. Callable interface is present in
java.lang package. java.util.concurrent package.
ThreadLocal class
• ThreadLocal class provides ThreadLocal variables.
• ThreadLocal class maintains values per thread basis.
• Each ThreadLocal object maintains a separate value ,
like userid, transactionid, etc.
• Thread can accesses its local value ,can manipulate
its value and even can remove its value.
• In every part of the code which is executed by the
thread , we can access its local variable.
• Example:
Consider a object which invokes some business
methods. We have a requirement to generate a unique
transaction id for each and every request and we have to
pass this transaction id to the business methods. For this
requirement we can use ThreadLocal to maintain a separate
transaction id for every request i.e. for every threads.
• Note:
1. ThreadLocal class introduced in 1.2 version and
enhanced in 1.5 version.
2. ThreadLocal can be associated with thread scope.
3. Total code which is executed by thread , has access to
the corresponding ThreadLocal variable.
4. A thread can access its own local variable and
cant access other thread’s local variable.
5. Once thread entered into dead state , all its local
variables are by default eligible for Garbage
Collector
Constructor:
ThreadLocal tl =new ThreadLocal();
creates a ThreadLocal variable
Methods:
1. Object get();
2. Object initialValue();
3. void set(Object newVal);