at ThreadDemo2.main(ThreadDemo2.java:10)
Some platforms won't provide support for thread priorities.
In Spite of setting highest priority to a thread , you may not get the desired output.
PREVENT THREAD EXECUTION
- yield()
- join()
- sleep()
yield() - causes to pass current executing thread to give the chance for waiting thread of same priority.
if there is no waiting thread or all waiting threads have low priority then same thread can continue its execution.
The thread which is yielded, when it will get the chance once again depends upon thread scheduler.
We can't expect exact immediate regaining the execution engine.
join() -
If a thread wants to wait until completing some other thread then we should go for join().
for ex. if a thread t1 wants to wait until completing t2 then t1 has to call t2.join()
If t1 executes t2.join() then immediately t1 will be entered into waiting state until t2 completes.
Once t2 completes then t1 can continue its execution.
public void final join() throws InterruptedException;
public void final join(long ms) throws InterruptedException;
while a thread waiting until completing some other thread then there may be a chance interrupted exception. Therefore every join method throws InterruptedException which is checked exception exception compulsory we should handle this exception either by using try catch or by throws keyword.
class MyThreadDemo extends Thread
{
static Thread mt;
public void run()
{
try{
mt.join();
}
catch(InterruptedException ie)
{
System.out.println(ie.getMessage());
}
for(int i=1;i<=10;i++)
{
System.out.println("Child Thread : "+i);
}
}
}
class ThreadDemo3
{
public static void main(String args[])
{
MyThreadDemo.mt=Thread.currentThread();
MyThreadDemo obj=new MyThreadDemo();
obj.start();
for(int i=1;i<=10;i++)
{
System.out.println("Main Thread : "+i);
}
}
}
If main thread also put obj.join() then a deadlock situation will arise.
If main thread put join on main thread itself then also deadlock situation will arise.
Thread.currentThread().join();
sleep() - If a thread don't want to perform any operation for a particular amount of time then we should go for sleep().
public static native void sleep(long ms) throws InterruptedException;
public static void sleep(long ms, int ns) throws InterruptedException;
Every sleep method throws IE Exception, which is checked exception hence whenever we are using sleep method , compulsory we should handle InterruptedException either by try catch or by throws keyword.
class ThreadDemo4
{
public static void main(String args[]) throws InterruptedException
{
for(int i=1;i<=10;i++)
{
System.out.println("Slider = "+i);
Thread.sleep(5000);
}
}
}
interrupt() - example of how a thread can interrupt another thread
class ThreadDemoInterrupt extends Thread
{
public void run()
{
try{
for(int i=1;i<=10;i++)
{
System.out.println("Lazy Thread = "+i);
Thread.sleep(2000);
}
}
catch(InterruptedException ie)
{
System.out.println("I got interrupted");
}
}
}
class ThreadDemo4
{
public static void main(String args[])
{
ThreadDemoInterrupt obj=new ThreadDemoInterrupt();
obj.start();
obj.interrupt();
System.out.println("End of main THread");
}
}
Note : Whenever we are calling interrupt() if the target thread not in sleeping state or waiting state then there is no impact of interrupt call immediately. Interrupt call will wait until target thread enter into sleeping or waiting state. If the target thread enter into sleeping or waiting state , immediately interrupt call will interrupt the target thread.
If the target thread never entered into sleep or waiting state in its lifetime then there is no impact of interrupt call. This is the only case where interrupt call will be wasted.
Synchronization - It is a modifier .It is only applicable for methods and block but not for classes and variables
If multiple threads try to operate simultaneously on a single java object then this type of problem is called object inconsistency problem.
To resolve data inconsistency we can use synchronized keyword.
if a method or block declared as synchronized then at a time only one thread is allowed to execute that method or block on the given object.
The main advantage of synchronized keyword is , we can resolve data inconsistency problems but the main disadvantage is , it increases waiting time of threads and creates performance problems. Hence if there is no specific requirement then it is not recommended to use synchronized keyword.
Internally synchronization concept is implemented by using lock.
Every object in java has a unique lock. Whenever we are using synchronized keyword then only lock concept will come into picture.
If a thread wants to execute a synchronized method on the given object , first it has to get lock of that object.
Once thread got the lock then it is allowed to execute any synchronized method on that object.
Once method execution completes , automatically thread releases lock. So acquiring and releasing lock internally takes care by JVM.
t1 got the lock and start execution of m1()
while t1 was executing t2 came but it will go into waiting state.
t3 came to access m2 method. But to execute m2 object lock is required which is currently with t1 therefore t3 will also go into waiting state.
t4 came to access m3, it will directly able to execute because no lock is required to execute a non-synchronized method.
NON-SYNCHRONIZED EXAMPLE
class NonSync
{
public static void main(String args[])
{
Display obj=new Display();
MyThr t1=new MyThr(obj,"Bikesh");
MyThr t2=new MyThr(obj,"Amitesh");
MyThr t3=new MyThr(obj,"Maurya");
t1.start();
t2.start();
t3.start();
}
}
class Display
{
public void wish(String name)
{
for(int i=1;i<=10;i++)
{
System.out.println("Good Morning : " + name);
try{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{}
}
}
}
class MyThr extends Thread
{
Display d;
String name;
public MyThr(Display d,String name)
{
this.d=d;
this.name=name;
}
public void run()
{
d.wish(name);
}
}
C:\Users\Aarchi\Desktop\Java Development>javac NonSync.java
C:\Users\Aarchi\Desktop\Java Development>java NonSync
Good Morning : Amitesh
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Amitesh
Good Morning : Bikesh
Good Morning : Maurya
Good Morning : Amitesh
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Amitesh
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Amitesh
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Amitesh
Good Morning : Maurya
Good Morning : Amitesh
Good Morning : Bikesh
Good Morning : Maurya
Good Morning : Amitesh
Good Morning : Bikesh
Good Morning : Maurya
Good Morning : Amitesh
Good Morning : Bikesh
Good Morning : Maurya
Good Morning : Amitesh
Good Morning : Bikesh
SYNCHRONIZED EXAMPLE
just add the synchronized modifier in the method
public synchronized void wish(String name)
C:\Users\Aarchi\Desktop\Java Development>javac NonSync.java
C:\Users\Aarchi\Desktop\Java Development>java NonSync
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Maurya
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Bikesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
Good Morning : Amitesh
If multiple thread operating on same object then only synchronization required.
In below case we have created two different object and t1 and t2 will lock obj1 and obj2, therefore synchronization is not required here. In spite of having synchronize method we'll get irregular output.
class NonSync
{
public static void main(String args[])
{
Display obj1=new Display();
Display obj2=new Display();
MyThr t1=new MyThr(obj1,"Bikesh");
MyThr t2=new MyThr(obj2,"Amitesh");
t1.start();
t2.start();
}
}
static synchronized method will resolve this issue
public static synchronized void wish(String name)
Class level lock - every class in java has a unique lock which is also known as class level lock.
If a thread wants to execute any static synchronized method then it require class level lock is required instead of object lock required.

class bank
{
public static void main(String args[])
{
locker l1=new locker();
locker l2=new locker();
MyThreadDemoBank1 t1=new MyThreadDemoBank1(l1,"Bikesh");
MyThreadDemoBank2 t2=new MyThreadDemoBank2(l2,"Amitesh");
t1.start();
t2.start();
}
}
class locker
{
static int amount=1000;
static int translimit=0;
public static synchronized void account(String name)
{
while (amount > 0)
{
translimit++;
int total=amount;
amount=amount-100;
try
{
Thread.sleep(1000);
}
catch (InterruptedException ie)
{
}
System.out.println("Transaction : "+total+" - 100 ( "+name+" withdraw) ="+amount);
if(translimit==5)
{translimit=0;break; }
}
}
}
class MyThreadDemoBank1 extends Thread
{
String name;
locker l;
public MyThreadDemoBank1(locker l,String name)
{
this.l=l;
this.name=name;
}
public void run()
{
l.account(name);
}
}
class MyThreadDemoBank2 extends Thread
{
String name;
locker l;
public MyThreadDemoBank2(locker l,String name)
{
this.l=l;
this.name=name;
}
public void run()
{
l.account(name);
}
}
C:\Users\Aarchi\Desktop\Java Development>javac bank.java
C:\Users\Aarchi\Desktop\Java Development>java bank
Transaction : 1000 - 100 ( Amitesh withdraw) =900
Transaction : 900 - 100 ( Amitesh withdraw) =800
Transaction : 800 - 100 ( Amitesh withdraw) =700
Transaction : 700 - 100 ( Amitesh withdraw) =600
Transaction : 600 - 100 ( Amitesh withdraw) =500
Transaction : 500 - 100 ( Bikesh withdraw) =400
Transaction : 400 - 100 ( Bikesh withdraw) =300
Transaction : 300 - 100 ( Bikesh withdraw) =200
Transaction : 200 - 100 ( Bikesh withdraw) =100
Transaction : 100 - 100 ( Bikesh withdraw) =0
SYNCHRONIZED BLOCK
If very few lines of the code required 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 improves performance of the system/application.
synchronized(this)
{
..............
...............
..............
}
this is use to get the lock of current object
to get lock of particular project
synchronized(b)
{
.............
.............
.............
}
if a thread got the lock of object b then only it is allowed to execute this block.
to get class level lock
synchronized(Display.class)
{
...............
..............
..............
}
if a thread want to get the class level lock of class Display.
Lock concept only applicable for object types and class types but not for primitives.Hence we can't pass primitive type as argument to synchronized block otherwise we'll get compile time error saying "unexpected type fount int required ref."
int x=1;
ex:
synchronize(x)
{
..............
...........
...............
}
QUICK REVISION:
- What is synchronized keyword and where we can apply ?
- Explain advantage of synchronized keyword.
- Explain disadvantage of synchronized keyword.
- What is race condition ? (data inconsistency problem)
- What is object lock and when it is required ?
- What is class level lock and when it is required ?
- Difference between class level and object level lock ?
- What is synchronized block ?
- How to declare synchronized block to get lock of current object, class level lock ?
- what is the advantage of synchronize block over synchronized method.
- is a thread can acquire multiple locks simultaneously ? (Yes)