Created
February 5, 2013 05:08
-
-
Save tacksoo/4712307 to your computer and use it in GitHub Desktop.
Deadlock example caused by a incorrect nested synchronized block.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Bank { | |
private String name; | |
public Bank(String name) { | |
this.name = name; | |
} | |
public String getName() { | |
return name; | |
} | |
@Override | |
public boolean equals(Object obj) { | |
Bank b = (Bank) obj; | |
return b.getName().equals(name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BankAccount { | |
private int balance; | |
private Bank bank; | |
public BankAccount(int balance) { | |
this.balance = balance; | |
this.bank = new Bank("Bank of GGC"); | |
} | |
public synchronized void transfer(BankAccount target, int amount) throws DifferentBankException { | |
if (!bank.equals(target.getBank())) | |
throw new DifferentBankException(); | |
balance -= amount; | |
synchronized (target) { | |
target.balance += amount; | |
} | |
} | |
public synchronized int balance() { | |
return balance; | |
} | |
public Bank getBank() { | |
return bank; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BankAccountTransfer { | |
public static void main(String[] args) throws DifferentBankException, InterruptedException { | |
final BankAccount a = new BankAccount(10000); | |
final BankAccount b = new BankAccount(10000); | |
Thread t1 = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
for (int i = 0; i < 1000; i++) | |
{ | |
try { | |
a.transfer(b, 10); | |
System.out.println("Thread 1: " + i + " remaining: " + a.balance()); | |
} catch (DifferentBankException e) { | |
} | |
} | |
System.out.println("Thread 1 done!"); | |
} | |
}); | |
Thread t2 = new Thread(new Runnable() { | |
@Override | |
public void run() { | |
for (int i = 0; i < 1000; i++) | |
{ | |
try { | |
b.transfer(a, 10); | |
System.out.println("Thread 2: " + i + " remaining: " + b.balance()); | |
} catch (DifferentBankException e) { | |
} | |
} | |
System.out.println("Thread 2 done!"); | |
System.out.println(a.balance()); | |
} | |
}); | |
t1.start(); | |
t2.start(); | |
Thread.sleep(100000); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DifferentBankException extends Exception { | |
public DifferentBankException() { | |
} | |
public DifferentBankException(String message) { | |
super(message); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment