class myThread extends Thread { myThread() {} // default constructor private static long startTime = System.currentTimeMillis(); protected static void nap(int ms) { try { sleep(ms); } catch (InterruptedException e) { } } protected static long age() { return System.currentTimeMillis()-startTime; } protected static int getarg(int i, int n, String args[]) { int value; try { value = Integer.parseInt(args[i-1]); } catch (ArrayIndexOutOfBoundsException e) { return n; } catch (NumberFormatException e) { return n; } return value; } protected static float getarg(int i, float f, String args[]) { float value; try { value = Float.valueOf(args[i-1]).floatValue(); } catch (ArrayIndexOutOfBoundsException e) { return f; } catch (NumberFormatException e) { return f; } return value; } } class monitorShowSigDis extends myThread { monitorShowSigDis() {} public synchronized void gotoSleep(int id) { System.out.println ("Process "+ id +" enters monitor sleep proc at time "+ age()); nap(100); System.out.println ("Process "+ id +" queues on c.v. sleep proc at time "+ age()); try {wait();} catch (InterruptedException e) {} System.out.println ("Process "+ id +" awakes on c.v. sleep proc at time "+ age()); nap(100); System.out.println ("Process "+ id +" leaves monitor sleep proc at time "+ age()); } public synchronized void wakeUp(int id) { System.out.println ("Process "+ id +" enters monitor wake proc at time "+ age()); nap(1000); System.out.println ("Process "+ id +" signals c.v in wake proc at time "+ age()); notify(); System.out.println ("Process "+ id +" continues in wake proc at time "+ age()); nap(100); System.out.println ("Process "+ id +" signal two! in wake proc at time "+ age()); notify(); nap(100); System.out.println ("Process "+ id +" leaves monitor wake proc at time "+ age()); } } class sleeperThread extends myThread { int id = 0; monitorShowSigDis mssd = null; private sleeperThread() {} sleeperThread(int id, monitorShowSigDis mssd) { this.id = id; this.mssd = mssd; } public void run() { nap(id*1000); System.out.println ("Sleeper "+ id +" wants to enter monitor sleep proc at time "+ age()); mssd.gotoSleep(id); System.out.println ("Sleeper "+ id +" done at time "+ age()); } } class wakerThread extends myThread { int id = 0; monitorShowSigDis mssd = null; private wakerThread() {} wakerThread(int id, monitorShowSigDis mssd) { this.id = id; this.mssd = mssd; } public void run() { nap(2500); System.out.println ("Waker 9 wants to enter monitor wake proc at time "+ age()); mssd.wakeUp(9); System.out.println ("Waker 9 done at time "+ age()); } } class driverShowSigDis { /* * This example shows that Java wait/notify use the `signal and continue' * signaling discipline. One may generate multiple signals inside a * monitor and continue executing inside the monitor until a return. * IMPORTANT NOTE: it is possible that a signaled process may not resume * inside the monitor until after another process that was blocked on a * method call enters and leaves (or waits inside) the monitor. This * can be seen happening in the sample output shown below. Sleeper 3 * gets in the monitor before Sleepers 1 and 2 proceed after being * signaled. Caveat programmer! */ private static sleeperThread sT[]; private static wakerThread wT = null; private static monitorShowSigDis mssd = null; public static void main(String arg[]) { mssd = new monitorShowSigDis(); sT = new sleeperThread[3]; for (int i = 0; i<3; i++) sT[i] = new sleeperThread(i+1, mssd); wT = new wakerThread(9, mssd); for (int i = 0; i<3; i++) sT[i].start(); wT.start(); } } /* ............... Example compile and run(s) % $JAVAHOME/bin/javac showMonitorSigDis.java % $JAVAHOME/bin/java driverShowSigDis Sleeper 1 wants to enter monitor sleep proc at time 1051 Process 1 enters monitor sleep proc at time 1087 Process 1 queues on c.v. sleep proc at time 1200 Sleeper 2 wants to enter monitor sleep proc at time 2049 Process 2 enters monitor sleep proc at time 2058 Process 2 queues on c.v. sleep proc at time 2169 Waker 9 wants to enter monitor wake proc at time 2559 Process 9 enters monitor wake proc at time 2570 Sleeper 3 wants to enter monitor sleep proc at time 3059 Process 9 signals c.v in wake proc at time 3580 Process 9 continues in wake proc at time 3590 Process 9 signal two! in wake proc at time 3700 Process 9 leaves monitor wake proc at time 3819 Waker 9 done at time 3828 Process 3 enters monitor sleep proc at time 3837 Process 3 queues on c.v. sleep proc at time 3949 Process 1 awakes on c.v. sleep proc at time 3958 Process 1 leaves monitor sleep proc at time 4070 Sleeper 1 done at time 4081 Process 2 awakes on c.v. sleep proc at time 4089 Process 2 leaves monitor sleep proc at time 4199 Sleeper 2 done at time 4207 ^C */