001package edu.pdx.cs410J.net;
002
003/**
004 * This class demonstrates obtains a lock before access the
005 * <code>BankAccount</code>.  That way, it always sees a consistent
006 * view of the account. 
007 */
008public class SynchronizedATM extends ATM {
009  public SynchronizedATM(String name, BankAccount account, 
010                         int[] transactions) {
011    super(name, account, transactions);
012  }
013
014  /**
015   * Perform each transaction on the account
016   */
017  public void run() {
018    for (int i = 0; i < transactions.length; i++) {
019      // Get the lock on the account
020      synchronized(account) {
021        // Get the balance
022        int balance = account.getBalance();
023        out.println(this.name + " got balance " + balance);
024        
025        // Perform the operation
026        out.println(this.name + " perform " + transactions[i]);
027        balance += transactions[i];
028        
029        // Set the balance
030        out.println(this.name + " set balance to " + balance);
031        account.setBalance(balance);
032      }
033      // Give up the lock
034    }
035  }
036
037  /**
038   * Create a couple of accounts and have them all perform the same
039   * transactions, but in different orders.
040   */
041  public static void main(String[] args) {
042    BankAccount account = new BankAccount();
043    account.setBalance(1000);
044    out.println("Initial balance: " + account.getBalance());
045
046    // Make some ATMs
047    int[] trans1 = {-200, 400, 100, -300};
048    ATM atm1 = new SynchronizedATM("ATM1", account, trans1);
049    int[] trans2 = {400, 100, -300, -200};
050    ATM atm2 = new SynchronizedATM("ATM2", account, trans2);
051    int[] trans3 = {-300, -200, 100, 400};
052    ATM atm3 = new SynchronizedATM("ATM3", account, trans3);
053
054    // Make some threads and start them
055    Thread t1 = new Thread(atm1);
056    t1.start();
057    Thread t2 = new Thread(atm2);
058    t2.start();
059    Thread t3 = new Thread(atm3);
060    t3.start();
061
062    // Wait for all threads to finish
063    try {
064      t1.join();
065      t2.join();
066      t3.join();
067
068    } catch (InterruptedException ex) {
069      return;
070    }
071
072    out.println("Final balance: " + account.getBalance());
073  }
074
075}