/* * ThreadExample5 * by Robert Keller * * Two threads are created. Each sleeps for an amount 'delay' of * milliseconds, then wakes up and prints its step number. * * Each also increments a common counter. We wish to illustrate * prevention of race conditions using 'synchronized' method. */ class ThreadExample5 implements Runnable { Thread myThread; // Thread object for control int myID; // Identifier for this "thread" int step; // Step number of this "thread" int totalSteps; // Total number of steps int delay; // delay milliseconds static long count; // counter /** * Construct a ThreadExample5 with the specified ID and delay value. */ public ThreadExample5(int myID, int delay, int totalSteps) { this.myID = myID; this.delay = delay; this.totalSteps = totalSteps; myThread = new Thread(this); step = 1; } /** * Start this thread. * The run method will be called. */ public void start() { myThread.start(); } /** * Join with this thread, meaning wait until it has completed. */ public void join() throws InterruptedException { myThread.join(); } /** * Interrupt this thread. */ public void interrupt() throws InterruptedException { myThread.interrupt(); } /** * Increment the counter and show the result * Note that declaring static makes the synchronization on the class * rather than the object as for the non-static case. * We need this because there are two separate * 'thread's, which are separate objects. */ static synchronized public long increment() { count++; return count; } /** * The run() method required to implement the Runnable interface. */ public void run() { while( step <= totalSteps ) { // try/catch is needed because sleep can throw an exception. try { myThread.sleep(delay); System.out.println("thread " + myID + " is at step " + step + " count is " + increment()); step++; } catch( InterruptedException e ) { System.out.println("thread " + myID + " interrupted at step " + step); return; } catch( Exception e ) { } } } public static void main(String arg[]) { ThreadExample5 thread1 = new ThreadExample5(1, 2, 10000); ThreadExample5 thread2 = new ThreadExample5(2, 1, 10000); thread1.start(); thread2.start(); try { thread2.join(); System.out.println("thread 2 terminates"); thread1.join(); System.out.println("thread 1 terminates"); } catch( InterruptedException e ) { } } }