Updated May 31, 2023
Introduction to Deadlock in Java
In Java, Deadlock is a situation of multithreading where thread 1 waits for an object lock attained by thread 2, and thread 2 waits for an object lock attained by thread 1. Here, both thread 1 and thread 2 wait for each other to release the lock. Multithreaded programs in Java can cause Deadlock as the keyword synchronized blocks the executing thread while waiting for a monitor or lock linked with the object mentioned. Let us see the working and examples of Deadlock in the following sections.
How does Deadlock work?
As discussed, the synchronized method can lock a particular portion of the code. For each object in Java, a lock will be there, and Synchronization is a technique to lock a function or block of code to ensure that only 1 thread can access that function or block of code at a time.
When a specific thread needs to execute a synchronized function, it first attempts to obtain the lock. At the same time, if another thread has already received the lock, the first thread waits until thread 2 releases the lock. Even though Synchronization prevents issues with data inconsistency, there is a synchronization issue.
Assume there are 2 threads, ‘Thread 1’ and ‘Thread 2’. Thread 1 has attained the lock of Object 1, and Thread 2 has attained the lock of Object 2. Thread 1, which executes method 1, wants to attain the lock on Object 2. However, Thread 2 already attains the lock on Object 2.
In addition, Thread 2 also needs to attain the lock on Object 1; however, Thread 1 has a lock on Object 1. Here, both threads, Thread 1 and Thread 2, can’t complete their execution and wait for the lock forever. This situation is called Deadlock.
Examples of Deadlock in Java
Given below are the examples mentioned:
Example #1
Java program to implement Deadlock.
Code:
public class DeadLockExample {
//main method
public static void main(String[] args) throws InterruptedException {
//create three objects 1, 2 and 3
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
//create three threads 1, 2 and 3
Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1");
Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2");
Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3");
//start thread 1
th1.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
//start thread 2
th2.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
//start thread 3
th3.start();
}
}
class SynchronizationThread implements Runnable
{
private Object o1;
private Object o2;
public SynchronizationThread(Object o1, Object o2){
this.o1=o1;
this.o2=o2;
}
//function run
@Override
public void run() {
//store the name of the thread
String nm = Thread.currentThread().getName();
System.out.println( nm + " attaining lock on "+ o1 ) ;
synchronized (o1)
{
System.out.println( nm + " attained lock on "+ o1 ) ;
work();
System.out.println( nm + " attaining lock on "+ o2 ) ;
synchronized (o2) {
System.out.println( nm + " attained lock on "+ o2 );
work();
}
System.out.println( nm + " released lock on "+ o2 ) ;
}
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " completed execution.") ;
}
//function work
private void work() {
try {
//thread sleeps
Thread.sleep(30000);
}
//catch the exception
catch (InterruptedException exc)
{
exc.printStackTrace();
}
}
}
Output:
Example #2
In this program, 3 threads running share a resource, and they run in a way that attains lock on object 1, but when it tries to attain lock on object 2, it goes into a wait state. To prevent Deadlock, you can rewrite the code as follows.
Code:
public class DeadLockExample {
public static void main(String[] args) throws InterruptedException {
Object o1 = new Object();
Object o2 = new Object();
Object o3 = new Object();
Thread th1 = new Thread(new SynchronizationThread(o1, o2), "thread 1");
Thread th2 = new Thread(new SynchronizationThread(o2, o3), "thread 2");
Thread th3 = new Thread(new SynchronizationThread(o3, o1), "thread 3");
//start thread 1, 2 and 3
th1.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
th2.start();
//thread sleeps for 5000 seconds
Thread.sleep(5000);
th3.start();
}
}
class SynchronizationThread implements Runnable{
private Object o1;
private Object o2;
public SynchronizationThread(Object o1, Object o2){
this.o1=o1;
this.o2=o2;
}
//function run
@Override
public void run() {
//store the name of the thread
String nm = Thread.currentThread().getName();
System.out.println( nm + " attaining lock on "+ o1 ) ;
synchronized (o1)
{
System.out.println( nm + " attained lock on "+ o1 ) ;
work();
}
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " acquiring lock on " + o2 );
synchronized (o2) {
System.out.println( nm + " attained lock on "+ o2 );
work();
}
System.out.println( nm + " released lock on "+ o2 ) ;
System.out.println( nm + " released lock on "+ o1 ) ;
System.out.println( nm + " completed execution.") ;
}
//function work
private void work() {
try {
//thread sleeps
Thread.sleep(30000);
}
//catch the exception
catch (InterruptedException exc)
{
exc.printStackTrace();
}
}
}
Output:
How to Avoid Deadlock in Java?
Following are the guidelines that help in avoiding deadlock situations.
1. Avoid locks that are nested
Nested locks are one of the common reasons for causing deadlocks. Do not lock another resource if it already holds one to avoid Deadlock. If the user works with only 1 object, it is impossible to cause a deadlock.
2. Lock only what is required
People recommend locking only the necessary resources. However, some users may attempt to lock resources even when not required.
3. Avoid waiting indefinitely
Deadlock occurs if 2 threads wait for each other to complete indefinitely with the help of thread join. If the thread needs to wait for other threads to complete, it is good to use join with the maximum amount of time that has to wait for the thread to complete.
Recommended Articles
This is a guide to Deadlock in Java. Here we discuss the introduction, working, examples, and how to avoid Deadlock in Java. You may also look at the following articles to learn more –