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