// AccountDemo4.java // by Mark Weiss, Fall 2002 // Uses private private lock for critical section synchronization. // (instead of this). Sun reccommends this to prevent deadlock. // Same output as AccountDemo3.java class OverdraftException extends Exception { public OverdraftException( ) { } public OverdraftException( String msg ) { super( msg ); } } class Account { public void deposit( int d ) { synchronized( CRITICAL_SECTION_1 ) // use private lock { balance += d; System.out.println( "Deposit " + d ); CRITICAL_SECTION_1.notifyAll( ); // don't use notify!! } } public void withdraw( int d ) throws OverdraftException { try { synchronized( CRITICAL_SECTION_1 ) // use private lock { while ( balance < d ) { System.out.println( "withdraw " + d + " enters wait"); CRITICAL_SECTION_1.wait(); System.out.println( "withdraw " + d + " back from wait"); } balance -= d; System.out.println( "Withdrew " + d ); } } catch( InterruptedException e ) { throw new OverdraftException( "Interrupted " + d ); } } private int balance = 0; private Object CRITICAL_SECTION_1 = new Object( ); // private lock } 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 ); } 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 ); } } class AccountDemo4 { 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( ); } }