Deadlock describes a situation where two or more threads are blocked forever, waiting for each other.
Let’s consider an example, in the office we have shared Printer and Scanner where Employees has ability to do scanning and printing.
1. John has bunch of documents that it wants to Print first and also want to take a Scan later.
(Print and Scan)
2. Michael has bunch of documents that it wants to Scan first and also want to take a Print later.
(Scan and Print)
public class DeadlockExample {
public static void main(String[] args) {
Printer printer = new Printer();
Scanner scanner = new Scanner();
// John has bunch of documents that it wants to Print and also want to
// take a scan later
Thread t1 = new PrintAndScan(printer, scanner);
t1.setName("John");
t1.start();
// Michael has bunch of documents that it wants to Scan and also want to
// take a print later
Thread t2 = new ScanAndPrint(printer, scanner);
t2.setName("Michael");
t2.start();
}
}
// Thread which take multiple documents and for each document it does the
// Printing first and then Scans the document
// So it requires two resource Printer and Scanner.
class PrintAndScan extends Thread {
Printer printer;
Scanner scanner;
public PrintAndScan(Printer printer, Scanner scanner) {
this.printer = printer;
this.scanner = scanner;
}
@Override
public void run() {
// Do printing and scanning simultaneously.
synchronized (printer) {
System.out.println(Thread.currentThread().getName() + " thread acquired printer");
try {
// Do printing work
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Scan the documents already printed
System.out.println(Thread.currentThread().getName() + " thread is waiting for scanner");
synchronized (scanner) {
System.out.println(Thread.currentThread().getName() + " thread is scanning");
}
}
}
}
// Thread which take multiple documents and for each document it does the
// Scanning first and then Prints the document
// So it requires two resource Scanner and Printer.
class ScanAndPrint extends Thread {
Printer printer;
Scanner scanner;
public ScanAndPrint(Printer printer, Scanner scanner) {
this.printer = printer;
this.scanner = scanner;
}
@Override
public void run() {
// Do scanning and printing simultaneously.
synchronized (scanner) {
System.out.println(Thread.currentThread().getName() + " thread acquired scanner");
try {
// Do scanning work
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Print the documents already scanned
System.out.println(Thread.currentThread().getName() + " thread is waiting for printer");
synchronized (printer) {
System.out.println(Thread.currentThread().getName() + " thread is printing");
}
}
}
}
// Shared Resources
class Printer {
}
class Scanner {
}
Output: John thread acquired printer Michael thread acquired scanner John thread is waiting for scanner Michael thread is waiting for printer
Another Simple Deadlock Example:
public class MyDeadlock {
String str1 = "Java";
String str2 = "UNIX";
Thread trd1 = new Thread("My Thread 1") {
public void run() {
while (true) {
synchronized (str1) {
synchronized (str2) {
System.out.println(Thread.currentThread().getName() + " -- " + str1 + str2);
}
}
}
}
};
Thread trd2 = new Thread("My Thread 2") {
public void run() {
while (true) {
synchronized (str2) {
synchronized (str1) {
System.out.println(Thread.currentThread().getName() + " -- " + str2 + str1);
}
}
}
}
};
public static void main(String a[]) {
MyDeadlock mdl = new MyDeadlock();
mdl.trd1.start();
mdl.trd2.start();
}
}
Output: My Thread 1 -- JavaUNIX My Thread 1 -- JavaUNIX My Thread 1 -- JavaUNIX . .

