public class MissedNotify {
	public static void main(String argv[]) {	
		LockObj lo = new LockObj();
		Thread ts = new Thread(new Sleeper("sleep",lo,Integer.parseInt(argv[0])));
		ts.start();
		new Thread(new Sleeper("wakeUp",lo,Integer.parseInt(argv[1]))).start();
		
		try {
			Thread.sleep(2500);
		}  catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()
		
		ts.interrupt();
	} //main() 
} //class MissedNotify

class Sleeper implements Runnable {
	LockObj lo;
	int time;
	
	String command;
	public Sleeper(String command, LockObj lo, int time) {
		this.command = command;
		this.lo = lo;
		this.time = time;
	} //constructor
	
	public void run() {
		if( command.compareTo("sleep") == 0 )
			goToSleep();
		else
			wakeUp();
	} //run()
	
	public  void goToSleep() {
		try {
			Thread.sleep(time);
		} catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()

		synchronized(lo) {
			System.out.println("sleeping 'til notification ...");
			try {
				lo.wait();
			} catch (InterruptedException ie) {
				System.out.println("An InterruptedException caught\n"+ie.getMessage());
				ie.printStackTrace();
				System.exit(1);
			} //catch()		
			System.out.println("notified and awaked");
		} //synchronize
	} //goToSleep()
	
	public  void wakeUp() {
		try {
			Thread.sleep(time);
		} catch (InterruptedException ie) {
			System.out.println("An InterruptedException caught\n"+ie.getMessage());
			ie.printStackTrace();
			System.exit(1);
		} //catch()

		synchronized(lo) {
			System.out.println("Trying to awake ...");
			lo.notify();
		} //synchronize
	} //wakeUp()	
} //class Sleeper

class LockObj
{ } //class LockObj