/* TestUnsafe class, which extends Thread, and runs through one BankAcct object, and displays the balance as its running. */ public class TestUnsafe extends Thread{ //data members for this thread private String name; BankAcct ba; //start this method public static void main( String[] args ){ BankAcct ba = new BankAcct( 0 ); new TestUnsafe( "** " , ba ).start(); new TestUnsafe( " ++ " , ba).start(); new TestUnsafe( " == " , ba ).start(); new TestUnsafe( " //" , ba ).start(); } //constructor public TestUnsafe( String n , BankAcct ba ){ this.ba = ba; name = n; } //extending Thread public void run(){ doWork(); } //simply displays the bank balance before and after this thread //messes with the bankaccount public void doWork(){ System.out.println( name+" :doWork() - start : account bal = "+ba.get() ); ba.doNothing(); System.out.println( name+" :doWork() - end : account bal = "+ba.get() ); } }//end TestUnsafe class /* BankAcct is the thread-unsafe class that should do nothing (by adding and then removing money from the balance). However, the Test thread messes up the BankAcct balance as a bunch of them trample through this object. */ class BankAcct{ int bal; public BankAcct( int i ){ bal = i; } void doNothing(){ addRemove( 10 ); addRemove( 20 ); addRemove( 30 ); } void addRemove( int m ){ bal+=m; Util.sleepRandom(); bal-=m; } int get(){ return bal; } }//end BankAcct class class Util{ //this method simply puts whatever thread that's running through //the code to sleep for a random number of milliseconds. public static void sleepRandom(){ try{ Thread.currentThread().sleep( (long)(Math.random()*100) ); } catch(Exception e){ System.out.println( e ); } } }//end Util class