How to Create a Deadlock In Java with One Thread
A deadlock is a situation in computer programming where two or more processes are blocked, each waiting for the other to release a resource that they need in order to continue executing. As a result, all the processes remain blocked indefinitely and are unable to make further progress.
In the context of multithreading, a deadlock occurs when two or more threads are blocked, each waiting for a resource held by the other. This leads to a situation where all threads are blocked and unable to make progress, effectively halting the program.
Deadlocks can occur due to improper synchronization of resources or when locks are acquired in the wrong order.
Here is an example:
class DeadlockExample {
static Object lock1 = new Object();
static Object lock2 = new Object();
static class Thread1 implements Runnable {
public void run() {
synchronized (lock1) {
System.out.println("Thread 1: Holding lock 1...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
static class Thread2 implements Runnable {
public void run() {
synchronized (lock2) {
System.out.println("Thread 2: Holding lock 2...");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
public static void main(String[] args) {
Thread t1 = new Thread(new Thread1());
Thread t2 = new Thread(new Thread2());
t1.start();
t2.start();
}
}
The DeadlockExample
class defines two static objects, lock1
and lock2
, which will be used as the locks for the two threads.
There are two inner classes, Thread1
and Thread2
, which implement the Runnable
interface and define the run
method that will be executed by the threads.
In the run
method of Thread1
, the thread first acquires the lock on lock1
using the synchronized
keyword, and then prints a message indicating that it's holding the lock. It then waits for a short time using Thread.sleep(10)
. After the sleep, it tries to acquire the lock on lock2
and prints a message indicating that it's holding both locks.
Similarly, in the run
method of Thread2
, the thread first acquires the lock on lock2
using the synchronized
keyword, and then prints a message indicating that it's holding the lock. It then waits for a short time using Thread.sleep(10)
. After the sleep, it tries to acquire the lock on lock1
and prints a message indicating that it's holding both locks.
In the main
method, two threads are created, one for each of the Thread1
and Thread2
classes, and they are started using the start
method.
Since both threads are trying to acquire both locks in different orders, there is a chance that one of the threads will hold lock1
while the other is waiting for it, and the other will hold lock2
while the first is waiting for it. This leads to a deadlock situation, where both threads are stuck and unable to proceed, because each is waiting for the other to release the lock they need.