/**************************************************************************/ /*** ***/ /*** Bank.java ***/ /*** ***/ /*** A simple bank simulation using Java threads ***/ /*** C311 -- Programming Languages -- Spring 98 ***/ /*** ***/ /**************************************************************************/ interface Account { public int acctNumber(Teller t); public void setBalance(Teller t, int howmuch); public int balance(Teller t); } class Teller { public void deposit(Account a, int howmuch) { // Change this method so that updates to account balances // are synchronized. a.setBalance(this, a.balance(this) + howmuch); } public void withdraw(Account a, int howmuch) { // Change this method so that: // 1. Updates to account balances are synchronized. // 2. Customer threads that attempt to withdraw more than the // current balance of an account are delayed (using wait()) // until funds are available. a.setBalance(this, a.balance(this) - howmuch); } int id; public String toString() { return String.valueOf(id); } static int nextTellerNumber = 0; Teller() { id = nextTellerNumber++; } } /*----------------------------------------------------------------------* * Do not modify anything below here... * *----------------------------------------------------------------------*/ class AccountImpl implements Account { static int num_of_acct = 0; private int acctNo; private int balance = 0; private static int total = 0; public static int totalBalance() { return total; } private void delay() { for(int i=0; i<1000; i++) { Thread.currentThread().yield(); }; } AccountImpl() { acctNo = num_of_acct++; } public int acctNumber(Teller t) { return acctNo; } public void setBalance(Teller t, int howmuch) { delay(); synchronized (this) { total = total + (howmuch - balance); balance=howmuch; System.out.println("Account #" + acctNo + ": set to $" + howmuch + " by teller " + t); if (balance < 0) { System.out.println("Hey, account balance went negative!"); System.exit(1); } } } public int balance(Teller t) { delay(); System.out.println("Account #" + acctNo + ": balance is $" + balance + " (requested by teller " + t + ")"); return balance; } public String toString() { return String.valueOf(acctNo); } } class Customer extends Thread { int id; static int ids=0; Customer() { id = ids++; } protected void deposit(int t, int a, int amount) { System.out.println("Customer " + id + ": depositing " + amount + " in account #" + a + " using teller " + t); Bank.tellers[t].deposit(Bank.accts[a],amount); Bank.totalHoldings += amount; } protected void withdraw(int t, int a, int amount) { System.out.println("Customer " + id + ": withdrawing " + amount + " from account #" + a + " using teller " + t); Bank.tellers[t].withdraw(Bank.accts[a],amount); Bank.totalHoldings -= amount; } } class Cust0 extends Customer { public void run() { deposit(0,0,20); withdraw(0,0,100); deposit(0,1,100); } } class Cust1 extends Customer { public void run() { deposit(0,0,50); deposit(0,0,60); withdraw(0,1,22); deposit(1,1,200); } } class Cust2 extends Customer { public void run() { deposit(1,1,10); withdraw(1,1,50); deposit(1,0,20); } } class Cust3 extends Customer { public void run() { deposit(1,1,10); withdraw(1,1,100); } } class Bank { public final static int num_ac=4; public final static int num_te=2; public static int totalHoldings=0; static Teller[] tellers = new Teller[num_te]; public static Account[] accts = new Account[num_ac]; public static void main(String[] args) { for(int i=0;i