If a
threads are waiting for each other forever, then such type of situation is
called Deadlock. There is no resolution technique for deadlock but several
prevention techniques are possible.
public class
DeadlockDemo{
public static void
main(String[] args) {
final
String resource1 = "Java";
final
String resource2 = "Python";
Thread t1 = new
Thread(){
public void
run(){
synchronized(resource1)
{
System.out.println("Thread t1 holds resource1");
try{
Thread.sleep(100);
}
catch(Exception
e){}
synchronized(resource2)
{
System.out.println("Thread t1 holds resource2");
}
}
}
};
Thread t2 = new
Thread(){
public void
run(){
synchronized(resource2)
{
System.out.println("Thread t2 holds resource2");
try{
Thread.sleep(100);
}
catch(Exception
e){}
synchronized(resource1)
{
System.out.println("Thread t2 holds resource1");
}
}
}
};
t1.start();
t2.start();
}
}
Output –
Thread t2 holds resource2
Thread t1 holds resource1
Note – In the above example it
reach to deadlock as t1 is holding resource1 and t2 is holding resource2, but
still both are requesting the resource hold by others.
Synchronized – This keyword
is the reason why programs enter into deadlock. Hence by using synchronized
keyword we have to handle program execution carefully.
Example –
class
Demo{
int count;
public void
increment()
{
count++;
}
}
public class
SyncDemo {
public static void
main(String[] args) throws InterruptedException {
Demo c = new
Demo();
Thread t1 = new
Thread(()->{
for(int i=0;i<100;i++)
{
c.increment();
}
});
Thread t2 = new
Thread(()->{
for(int i=0;i<100;i++)
{
c.increment();
}
});
t1.start();
t1.join();
t2.start();
System.out.println(c.count);
}
}
Note – In the above example, as
we are supposed to get the value of count as 200 but all the time we will get
some random values between within 200. Because at some particular time when t1
holds the resource the same resource is being hold by t2, so it cannot update
the exact value. So to overcome with this kind of problem, where at a
particular time only one thread should invoke a particular method. Then we
should make that method synchronized which gives the facility not to hold
resource by many threads at a particular time. One thread releases the resource
then only other thread occupies it.
Example –
class
Demo{
int count;
public synchronized void increment()
{
count++;
}
}
public class
SyncDemo {
public static void
main(String[] args) throws InterruptedException {
Demo c = new
Demo();
Thread t1 = new
Thread(()->{
for(int i=0;i<100;i++)
{
c.increment();
}
});
Thread t2 = new
Thread(()->{
for(int i=0;i<100;i++)
{
c.increment();
}
});
t1.start();
t1.join();
t2.start();
System.out.println(c.count);
}
}
Output –
200
Synchronized is the
keyword applicable only for methods and the blocks, but not for variables and
class. If a method or block is declared as synchronized, then at a time only
one method is allowed to execute. The main advantage of synchronized keyword is
we can resolve data inconsistency problems. The main disadvantage of
synchronized keyword is – It increases waiting time of the threads and creates
performance problems on it. Hence, if there is no specific requirement then it
is never recommended to use synchronized keyword.
Every
object in java has a unique lock. Internally synchronization concept is
implemented by using lock concept. If a thread wants to execute any
synchronized method on the given object, first it has to get the lock of that
object. Once a thread gets the lock, then it allows execution of any
synchronized method on that object. Once a synchronized method execution is
complete, then thread releases the lock automatically. While a thread is
executing synchronized method on the given object, then the remaining threads
aren’t allowed to execute, any synchronized method simultaneously. The
remaining threads are allowed to execute any non synchronized method
simultaneously. Lock concept is implemented based on object and not on method.
Example –
class
Display
{
public synchronized void wish(String name)
{
for(int i=0;i<5;i++)
{
System.out.println("Welcome to CMP");
try{
Thread.sleep(1000);
}
catch(Exception
e){}
}
System.out.println(name);
}
}
class
MyThread4 extends Thread{
Display d;
String name;
public
MyThread4(Display d,String name)
{
this.d=d;
this.name=name;
}
public void
run()
{
d.wish(name);
}
}
public class
SyncDemo {
public static void
main(String[] args) throws InterruptedException {
Display d = new
Display();
MyThread4 mt1
= new MyThread4(d, "cmp");
MyThread4 mt2
= new MyThread4(d, "rakesh");
mt1.start();
mt2.start();
}
}
Output –
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
rakesh
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
Welcome to CMP
cmp