class OverdraftException extends Exception { public OverdraftException( ) { } public OverdraftException( String msg ) { super( msg ); } } class Account { public void deposit( int d ) { synchronized( CRITICAL_SECTION_1 ) { balance += d; CRITICAL_SECTION_1.notifyAll( ); } } public void withdraw( int d ) throws OverdraftException { try { synchronized( CRITICAL_SECTION_1 ) { while( balance < d ) CRITICAL_SECTION_1.wait(); balance -= d; } } catch( InterruptedException e ) { throw new OverdraftException( "Interrupted " + d ); } } private int balance = 0; private Object CRITICAL_SECTION_1 = new Object( ); } class WithdrawThread extends Thread { private int amount; private Account acc; public WithdrawThread( Account a, int d ) { amount = d; acc = a; } public void run( ) { try { acc.withdraw( amount ); System.out.println( "Withdrew " + amount ); } catch( OverdraftException e ) { System.out.println( "Overdraft " + e.getMessage( ) ); } } } class DepositThread extends Thread { private int amount; private Account acc; public DepositThread( Account a, int d ) { amount = d; acc = a; } public void run( ) { acc.deposit( amount ); System.out.println( "Deposit " + amount ); } } class AccountDemo5 { public static void main( String [] args ) { Account acc = new Account( ); Thread t1 = new WithdrawThread( acc, 100 ); Thread t2 = new WithdrawThread( acc, 75 ); Thread t3 = new WithdrawThread( acc, 25 ); Thread t4 = new DepositThread( acc, 20 ); Thread t5 = new DepositThread( acc, 180 ); t1.start( ); t2.start( ); t3.start( ); t4.setPriority( Thread.MIN_PRIORITY ); t4.start( ); try { Thread.sleep( 2000 ); } catch( InterruptedException e ) { } t5.setPriority( Thread.MIN_PRIORITY ); t5.start( ); } }