DEADLOCK IN JAVA MULTITHREADING

          What is Deadlock in Java




Deadlock in Java is a part of multithreading. 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.

 A Java multithreaded program may suffer from the deadlock condition because the synchronized keyword causes the executing thread to block while waiting for the lock, or monitor, associated with the specified object.

In simple words, Deadlock is a condition where the threads are waiting infinitely for the resources(locks).


So, an example:

Resource A and resource B are used by process X and process Y


  • X starts to use A.

  • X and Y try to start using B

  • Y 'wins' and gets B first

  • now Y needs to use A

  • A is locked by X, which is waiting for Y




In order for deadlock to occur, four conditions must be true.

Mutual exclusion - Each resource is either currently allocated to exactly one process or it is available. (Two processes cannot simultaneously control the same resource or be in their critical section).

Hold and Wait - processes currently holding resources can request new resources.

No preemption - Once a process holds a resource, it cannot be taken away by another process or the kernel.

Circular wait - Each process is waiting to obtain a resource which is held by another process.

Now Let’s Write a Program and See What’s the Issue With This Program....

There are two threads in the program and two locks are created. Each thread needs both locks to execute the critical section. Hence both threads are synchronized on these two locks but in a different order.

  1. The thread-1 first acquires lock1 and then lock2 to execute completely.
  2. But the thread-2 first acquires lock2 and then lock1 to execute completely.

Now let’s go through the program and find why the deadlock can occur?

public class Main {
public static Object lock1 = new Object();
public static Object lock2 = new Object();
public static void main(String[] args) {
new Thread1().start();
new Thread2().start();
}
private static class Thread1 extends Thread {
@Override
public void run() {
synchronized (lock1) {
System.out.println("Thread-1 acquired lock1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread-1 interrupted.");
}
System.out.println("Thread-1 waiting for lock2");
synchronized (lock2) {
System.out.println("Thread-1 acquired lock2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread-1 interrupted.");
}
}
System.out.println("Thread-1 releases lock2");
}
System.out.println("Thread-1 releases lock1");
}
}
private static class Thread2 extends Thread {
@Override
public void run() {
synchronized (lock2) {
System.out.println("Thread-2 acquired lock2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread-2 interrupted.");
}
System.out.println("Thread-2 waiting for lock1");
synchronized (lock1) {
System.out.println("Thread-2 acquired lock1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.println("Thread-2 interrupted.");
}
}
System.out.println("Thread-2 releases lock1");
}
System.out.println("Thread-2 releases lock2");
}
}
}


OUTPUT:




We can see that Thread-1 acquired lock1 and Thread-2 acquired lock2. Thread-2 is waiting for lock1 in order to execute its second synchronized block. Similarly, Thread-1 wants lock2 to execute its second synchronized block but lock2 is not available to acquire it as it is already acquired by Thread-2. Hence these threads are waiting infinitely for the locks in order to execute completely.



But.....the question remains "how to get rid of a Deadlock?" 🤔


Avoid Dead Lock condition

Deadlocks cannot be completely resolved. We can avoid dead lock condition by knowing its possibilities. It’s a very complex process and not easy to catch. But still if we try, we can avoid this. There are some methods by which we can avoid this condition.
 

1) Avoid Nested Locks : This is the main reason for dead lock. Dead Lock mainly happens when we give locks to multiple threads. Avoid giving lock to multiple threads if we already have given to one.


2) Avoid Unnecessary Locks : We should have lock only those members which are required. Having lock on unnecessarily can lead to dead lock.


3) Using thread join : A deadlock usually happens when one thread is waiting for the other to finish. In this case, we can use join with a maximum time that a thread will take.




. . . . . . .

If you liked my blog and want more blogs on topic related to Java Programming make sure to fill this feedback form and share as much as you can with your friends. It will boast up my self confidence and compassion towards CS field. THNX :)

                                                                👇

                                    https://forms.gle/kjReWXbuQ3gaBKDu7


Comments