PPL (201-1289101)

Bank Account in Java - Synchronization

Just the source (BankAccount) Just the source (Transfer) Back to Course Home Page

Question 1: Should the getBalance method be synchronized? Think of a situation involving transfer between accounts. Compare this with the discussion in the book on p.307 and Exercise 3.45. Explain the difference between the serializers discussed in the book and the monitors implemented in Java. (The basic question is: why don't we have a deadlock when the method BankAccount.transfer calls BankAccount.withdraw?)


public class BankAccount {

  private double balance;

  public BankAccount(double balance) {
    this.balance = balance;
  }

  public double getBalance() {
    return balance;
  }

  public synchronized void deposit(double amount) {
    balance += amount;
  }

  public synchronized void withdraw(double amount) 
    throws RuntimeException {
    if (amount > balance) {
      throw new RuntimeException("Overdraft");
    }
    balance -= amount; 
  }

  public synchronized void transfer(double amount, BankAccount destination) {
    this.withdraw(amount);
    Thread.yield();   //Force a context switch
    destination.deposit(amount);
  }
}

Here is the code to test the transfer method and that demonstrates the need for synchronized on getBalance:


import BankAccount;

public class Transfer implements Runnable {
  public static void main(String[] args) {
    Transfer x = new Transfer(new BankAccount(100.0), 
                              new BankAccount(100.0), 
                              50.0);
    Thread t = new Thread(x);  // x implements runnable and 
                               // therefore can be attached to a thread
    t.start();      
    Thread.yield();  // Force a context switch
    
    System.out.println("Account a has $"+x.a.getBalance());
    System.out.println("Account b has $"+x.b.getBalance());
  }

  public BankAccount a, b;
  public double amount;

  public Transfer(BankAccount a, BankAccount b, double amount) {
    this.a = a;
    this.b = b;
    this.amount = amount;
  }

  public void run() {
    System.out.println("Before transfer a has $"+a.getBalance());
    System.out.println("Before transfer b has $"+b.getBalance());
    a.transfer(amount, b);
    System.out.println("After transfer a has $"+a.getBalance());
    System.out.println("After transfer b has $"+b.getBalance());
  }    
}


Last modified June 4th, 1997 Michael Elhadad