Using wait/notify correctly: why does this code fail at runtime?\n\npublic class Test {\n public static void main(String[] args) {\n final Foo f = new Foo();\n Thread t = new Thread(new Runnable() { public void run() { f.doStuff(); } });\n Thread g = new Thread() { public void run() { f.doStuff(); } };\n t.start(); g.start();\n }\n}\nclass Foo {\n int x = 5;\n public void doStuff() {\n if (x < 10) {\n try { wait(); } catch (InterruptedException ex) { }\n } else {\n System.out.println("x is " + x++);\n if (x >= 10) { notify(); }\n }\n }\n}

Difficulty: Easy

Correct Answer: An exception occurs at runtime

Explanation:


Introduction / Context:
Object.wait() and Object.notify()/notifyAll() must be invoked by a thread that currently owns the object’s monitor; otherwise, the JVM throws IllegalMonitorStateException. This example intentionally calls wait/notify without synchronization to test your understanding of this precondition.



Given Data / Assumptions:

  • Two threads invoke Foo.doStuff() concurrently on the same Foo instance.
  • doStuff() calls wait() and notify() with no synchronized block or synchronized method.
  • x starts at 5, satisfying the x < 10 branch on first calls.


Concept / Approach:
Because neither doStuff() nor its caller holds Foo’s monitor (i.e., synchronized(this)), calling wait() immediately raises IllegalMonitorStateException at runtime. Likewise, notify() would also be illegal if reached. Proper usage requires doStuff() to be synchronized or to wrap wait/notify inside synchronized(this) {}.



Step-by-Step Solution:

Threads start and enter doStuff().Branch x < 10 taken → executes wait() without owning the monitor.The JVM throws IllegalMonitorStateException.Program terminates abnormally; no consistent printing occurs.


Verification / Alternative check:
Fix by declaring public synchronized void doStuff() and by using a condition loop (while (x < 10) wait();), then notify() inside the synchronized context when the condition changes.



Why Other Options Are Wrong:

  • Compilation is fine; the error is at runtime.
  • Printing “x is 5 x is 6” would require reaching the else branch and proper synchronization.
  • Hanging forever is not the observed behavior here; instead an immediate exception is thrown.


Common Pitfalls:
Forgetting to synchronize when using wait/notify; using if instead of while around wait, which can lead to spurious wakeup issues.



Final Answer:
An exception occurs at runtime

More Questions from Threads

Discussion & Comments

No comments yet. Be the first to comment!
Join Discussion