package ar.com.javacuriosities.threads.liveness; import java.util.concurrent.TimeUnit; /* * Nos referimos a un deadlock cuando un thread espera por otro que esta utilizando un recurso (File, DB Table, etc), * mientras que el otro thread tambiƩn esta esperando por el primer thread que esta utilizando el recurso que este necesita */ public class Deadlock { public static void main(String[] args) { BankAccount account1 = new BankAccount(1, 100d); BankAccount account2 = new BankAccount(2, 100d); Thread transfer1 = new Thread(new TransferTask(account1, account2), "TransferTask-1"); transfer1.start(); Thread transfer2 = new Thread(new TransferTask(account2, account1), "TransferTask-2"); transfer2.start(); } private static final class TransferTask implements Runnable { private BankAccount from; private BankAccount to; public TransferTask(BankAccount from, BankAccount to) { this.from = from; this.to = to; } public void run() { System.out.println("Executing transfer from: " + from + " to: " + to); BankAccount.transfer(from, to, 10d); } } private static final class BankAccount { private int id; private double balance; public BankAccount(int id, double balance) { this.id = id; this.balance = balance; } public void withdraw(double amount) { // Simulamos algo de IO como por ejemplo acceso a una DB try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { // Log and Handle exception e.printStackTrace(); } balance -= amount; } public void deposit(double amount) { // Simulamos algo de IO como por ejemplo acceso a una DB try { TimeUnit.MILLISECONDS.sleep(10); } catch (InterruptedException e) { // Log and Handle exception e.printStackTrace(); } balance += amount; } @Override public String toString() { return "BankAccount [id=" + id + ", balance=" + balance + "]"; } public static void transfer(BankAccount from, BankAccount to, double amount) { synchronized (from) { System.out.println("Lock acquired: " + from + " by" + Thread.currentThread().getName()); from.withdraw(amount); synchronized (to) { System.out.println("Lock acquired: " + to + " by" + Thread.currentThread().getName()); to.deposit(amount); } } } } }