Thread deadlock is a hot topic in multi-threading, which makes multi-threading a complex area for beginners. Thread deadlock is a situation, where more than one threads with a shared resource are waiting for other thread(s) to release the lock on that shared resource without doing anything usefully.
This article explains the dead lock using a simple Java application, which simulates a bank transaction.
Create an Account class:
public class Account {
private final String name;
private double balance;
public Account(String name) {
this.name = name;
}
public void withdraw(double amount) {
this.balance -= amount;
}
public void deposit(double amount) {
this.balance += amount;
}
public double getBalance() {
return this.balance;
}
@Override
public String toString() {
return name;
}
}
public class Transaction extends Thread {
private final String id;
private final Account from;
private final Account to;
private final double amount;
public Transaction(String id, Account from, Account to, double amount) {
this.id = id;
this.from = from;
this.to = to;
this.amount = amount;
}
@Override
public void run() {
// Acquire the lock of Account 'from'
synchronized (from) {
from.withdraw(amount);
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
// Acquire the lock of Account 'to'
synchronized (to) {
to.deposit(amount);
}
// Release the lock of Account 'to'
}
// Release the lock of Account 'from'
System.out.println(amount + "is transfered from " + from + " to " + to);
}
}
Inside the run method, this class synchronizes the '
from' account first and without releasing the lock, it acquires (at least tries to acquire) the lock of '
to' account. Synchronization is the technique of avoiding data corruption or unexpected results in a shared resource environment. For more details about synchronization, visit to this article:
Thread Synchronization in Java.
Create a Main class to execute the application:
public class Main {
public static void main(String[] args) {
final Account accA = new Account("Acc 1");
final Account accB = new Account("Acc 2");
accA.deposit(1000.00);
accB.deposit(1000.00);
Transaction t1 = new Transaction("T01", accA, accB, 100.00);
Transaction t2 = new Transaction("T02", accB, accA, 500.00);
t1.start();
t2.start();
}
}
Suppose there are two customers want to transfer some amount of money to each other from their account at the same time, there is a possibility of getting thread deadlock during this transaction. If you run this program multiple times, sometimes you will not get any outputs in the terminal. Let's analyze the execution of this code into two cases.
Case 1:
Step 1: Transaction 1 starts first, receives the lock of account A and withdraws the money.