import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class Test1 {
public static void main(String[] args) {
Bank bank = new Bank(10, 500); // Shared data.
for (int i = 0; i < bank.size(); ++i) {
BankTransfer bt = new BankTransfer(bank, i, 500);
Thread thread = new Thread(bt);
thread.start();
}
}
}
class Bank {
private ReentrantLock lock;
private Condition condition;
private double[] accounts;
public Bank(int n, double initialBalance) {
accounts = new double[n];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = initialBalance;
}
lock = new ReentrantLock();
condition = lock.newCondition();
}
public int size() {
return accounts.length;
}
public double getTotalBalance() {
double totalBalance = 0;
lock.lock();
try {
for (int i = 0; i < accounts.length; ++i) {
totalBalance += accounts[i];
}
} finally {
lock.unlock();
}
return totalBalance;
}
public void transfer(int from, int to, double amount) {
lock.lock();
try {
while (accounts[from] < amount) {
condition.await();
}
System.out.print(Thread.currentThread());
accounts[from] -= amount;
accounts[to] += amount;
System.out.print("\t" + amount + " from " + from + " to " + to);
System.out.println("\tTotal balance: " + getTotalBalance());
condition.signalAll();
} catch (InterruptedException e) {
} finally {
lock.unlock();
}
}
}
class BankTransfer implements Runnable {
private Bank bank;
private int fromAcount;
private double maxAmount;
public static final int DELAY = 4000;
public BankTransfer(Bank bank, int fromAcount, double maxAmount) {
this.bank = bank;
this.fromAcount = fromAcount;
this.maxAmount = maxAmount;
}
public void run() {
try {
while (true) {
int toAcount = (int) (bank.size() * Math.random());
int amount = (int)(maxAmount * Math.random());
bank.transfer(fromAcount, toAcount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
} catch (InterruptedException e) {
}
}
}