package dk.itu.voop.thread; public class WaitNotifyTest { static class SharedState { public void letsWait() throws InterruptedException { trace("waiting for lock"); synchronized(this) { trace("holding lock"); trace("spending some time"); Thread.sleep(100); trace("calling wait()"); trace("giving up lock"); trace("blocks..."); wait(); trace("woke up"); trace("holding lock again"); trace("returned from wait"); } trace("no longer holding lock"); } public void notifyWaiter() throws InterruptedException { trace("waiting for lock"); synchronized(this) { trace("holding lock"); trace("calling notify()"); notify(); trace("returned from notify"); trace("spending some time"); Thread.sleep(100); trace("giving up lock"); trace("waking up other thread"); } trace("no longer holding lock"); } } static class Waiter implements Runnable { SharedState _sharedState; Waiter(SharedState sharedState) { _sharedState = sharedState; } public void run() { try { _sharedState.letsWait(); } catch(InterruptedException e) { trace("was interrupted"); } } } static class Notifier implements Runnable { SharedState _sharedState; Notifier(SharedState sharedState) { _sharedState = sharedState; } public void run() { try { _sharedState.notifyWaiter(); } catch(InterruptedException e) { trace("was interrupted"); } } } public static void main(String[] args) throws InterruptedException { SharedState sharedState = new SharedState(); Thread waiterThread = new Thread(new Waiter(sharedState), "waiter"); Thread notifierThread = new Thread(new Notifier(sharedState), "notifier"); waiterThread.start(); Thread.sleep(50); notifierThread.start(); } static void trace(String msg) { System.out.println(Thread.currentThread().getName() + ": " + msg); } } /* $ ./runwaitnotify.sh waiter: waiting for lock waiter: holding lock waiter: spending some time notifier: waiting for lock waiter: calling wait() waiter: giving up lock waiter: blocks... notifier: holding lock notifier: calling notify() notifier: returned from notify notifier: spending some time notifier: giving up lock notifier: waking up other thread waiter: woke up waiter: holding lock again waiter: returned from wait waiter: no longer holding lock notifier: no longer holding lock */