FileDocCategorySizeDatePackage
Bank3.javaAPI DocExample2135Mon Oct 16 19:44:08 BST 2000None

Bank3.java

// File:    Bank1.java
// T Balls : March 1998
// Modified from Core Java p524ff
// C Horstmann (Ed1)
// Correct use of wait() and notifyAll()
// in synchronized method

class Bank
{  public static void main( String[] args )
   {  Bank theBank = new Bank();
      for( int i=0; i < NO_ACCS; i++ )
      {  new TransactionGenerator( theBank, i ).start();
      }
   }

   public static final int NO_ACCS = 10;
   public static final int INIT_BAL = 10000;
   private int noTransacts;
   private int[] account;
   
   public Bank()
   {  account = new int[ NO_ACCS ];
      for( int i = 0; i < account.length; i++ )
      {  account[i] = INIT_BAL;
      }
      noTransacts = 0;
      currentState();
   }

   public void currentState()
   {  int bal = 0;
      for( int i=0; i < account.length; i++ )
      {  bal += account[i];
      }
      System.out.println( "Transactions:\t" + noTransacts +
                          "\tTotal balance:\t" + bal );
   }

   public synchronized void transfer( int amount, int from, int to )
   {  if( account[from] < amount )
      {  System.out.println( "Account: " + from + " has less than " + amount );
      }
      while( account[from] < amount )
      {  try
         {  wait();
         }
         catch( InterruptedException e ) {}
      }

      account[from] -= amount;
/**/  Thread.yield();
      account[to] += amount;

      noTransacts += 1;
      if( noTransacts%100 == 0 )
      {  currentState();
      }
      notifyAll();
   }
}

class TransactionGenerator extends Thread
{  public TransactionGenerator( Bank b, int account )
   {  theBank = b;
      from = account;
   }
   
   private int from;
   private Bank theBank;

   public void run()
   {  while( true )
      {  // generate a destination account
         int to;
         do
         {  to = (int)(Math.random() * (Bank.NO_ACCS-1));
         } while( to == from ); // need different numbers
         int amount = (int)((Math.random() * Bank.INIT_BAL)/2)+1;
         theBank.transfer( amount, from, to );
         yield();
      }
   }
}