==
package Demo13;
/**
* Title -- Advanced Java_ Multi-threading Part 11 - Deadlock
*
* @author Dharmaraj.Net
*/
public class App {
public static void main(String[] args) throws Exception{
final Runner runner = new Runner();
Thread t1 = new Thread(new Runnable() {
public void run() {
try {
runner.firstThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
runner.secondThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
runner.finished();
}
}
============
package Demo13;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Runner {
private Account acc1 = new Account();
private Account acc2 = new Account();
private Lock lock1 = new ReentrantLock();
private Lock lock2 = new ReentrantLock();
private void acquireLock(Lock firstLock, Lock secondLock) throws InterruptedException {
while(true){
//Acquire lock
boolean getFirstLock = false;
boolean getSecondLock = false;
try {
getFirstLock = firstLock.tryLock();
getSecondLock = secondLock.tryLock();
} finally{
if(getFirstLock && getSecondLock)
{
return;
}
if(getFirstLock){
firstLock.unlock();
}
if(getSecondLock){
secondLock.unlock();
}
}
//Locks not acquire
Thread.sleep(1);
}
}
public void firstThread() throws InterruptedException {
Random random = new Random();
for (int i = 0; i < 10000; i++) {
acquireLock(lock1, lock2);
lock2.lock();
try {
Account.transfer(acc1, acc2, random.nextInt(100));
} finally {
lock1.unlock();
lock2.unlock();
}
}
}
public void secondThread() throws InterruptedException {
Random random = new Random();
for (int i = 0; i < 10000; i++) {
acquireLock(lock2, lock1);
try {
Account.transfer(acc2, acc1, random.nextInt(100));
} finally {
lock1.unlock();
lock2.unlock();
}
}
}
public void finished() {
System.out.println("Account 1 Balance " + acc1.getBalance());
System.out.println("Account 2 Balance " + acc2.getBalance());
System.out.println("Total Balance "
+ (acc1.getBalance() + acc2.getBalance()));
}
}
==========
package Demo13;
public class Account {
private int balance = 10000;
public void deposit(int amount) {
balance += amount;
}
public void withdraw(int amount) {
balance -= amount;
}
public static void transfer(Account acc1, Account acc2, int amount) {
acc1.withdraw(amount);
acc2.deposit(amount);
}
public int getBalance() {
return balance;
}
========