A deadlock is when two or more processes share common resources and hold some resource while waiting for another resource that is acquired by the other processes.
Let’s take a real-life scenario. We have a desktop and laptop, as well as two resources: a printer and a scanner. The desktop is accessing the printer and locked it, while the laptop is accessing the scanner and locked it.
Now, the scanner will not be available for the desktop, as it is already acquired by the desktop. The same goes for the printer. Hence, this situation is a deadlock.
Let’s take a look at the code now.
class DeadLock {static final String resource1= "Printer";static final String resource2= "Scanner";public static void main(String[] args) {ThreadDemo1 Thread1 = new ThreadDemo1();ThreadDemo2 Thread2 = new ThreadDemo2();Thread1.start();Thread2.start();}private static class ThreadDemo1 extends Thread {public void run() {synchronized (resource1) {System.out.println("Desktop "+ ": locked" + resource1);try {Thread.sleep(1000);} catch (Exception e) {}}System.out.println("Desktop " + ": waiting for" + resource2+"......");synchronized (resource2) {System.out.println("Desktop "+ ": locked" + resource2);}}}private static class ThreadDemo2 extends Thread {public void run() {synchronized (resource2) {System.out.println("Laptop "+": locked" + resource2);try {Thread.sleep(100);} catch (Exception e) {}}System.out.println("Laptop " + ": waiting for" + resource1+"......");synchronized (resource1) {System.out.println("Laptop "+ ": locked" + resource1);}}}}
In lines 2 and 3, we create Scanner
and Printer
.
In line 4, inside the main()
function, we create two objects of ThreadDemo1
and ThreadDemo2
class and call them with the start()
method.
From lines 10 to 24, inside the ThreadDemo1
class, we implement the run()
method (as we have extended the ThreadDemo1
class from the built-in Thread
class), and acquire the lock on resource1
(printer
).
Then, in line 15, we put the thread on sleep, and in line 19, we demand resource2
(scanner
) by the desktop.
From lines 25 to 39, inside the ThreadDemo2
class, we implement the run()
method and acquire the lock on resource2
(scanner
). We put the thread on sleep and demand resource1
(printer
) by the laptop.
We use synchronized()
to first acquire a lock on printer
for desktop
and put it in wait, then we do the same thing for scanner
. Hence, the printer
will be locked by desktop
, and scanner
by laptop
, and both desktop
and laptop
need the scanner and printer, respectively, to terminate the process.
Both the threads will create a deadlock scenario.