reason of IllegalMonitorStateException if I use wait within sync block

concurrency, java, synchronization, wait

Solution

You are synchronizing on `monitor`, so you should `wait()` on monitor, too:

monitor.wait();

Right now you are waiting on `this`, which is not the owner of the monitor because synchronization is on `monitor`.

Note that of course the `notify` should also be done on the `monitor` object, and that you might want to consider using `notify`/`notifyAll` in both threads. Otherwise it may happen that one thread starves waiting for a missing notification. Using a timeout (the overloaded version of `wait`) might also be a good idea to catch corner cases.

Problem

I try to understand java core synchronization. I wrote code sample: Program should write left right 10 times ``` package concurrency; public class LeftRightWaitNotifyExample { final static String str = "1"; public static void main(String[] args) { new LeftLegThread(str).start(); new RightLegThread(str).start(); } } class LeftLegThread extends Thread { String monitor; public LeftLegThread(String str) { monitor = str; } @Override public void run() { try { makeStep(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void makeStep() throws InterruptedException { synchronized (monitor) { for (int i = 0; i < 10; i++) { System.out.println("Left "); wait(); } } } } class RightLegThread extends Thread { String monitor; public RightLegThread(String str) { monitor = str; } @Override public void run() { try { makeStep(); } catch (InterruptedException e) { } } private void makeStep() throws InterruptedException { synchronized (monitor) { while (true) { System.out.println("Right "); notify(); wait(); } } } } ``` I get this output: ``` Left Right Exception in thread "Thread-0" java.lang.IllegalMonitorStateException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:485) at concurrency.LeftLegThread.makeStep(LeftRightWaitNotifyExample.java:35) at concurrency.LeftLegThread.run(LeftRightWaitNotifyExample.java:23) Exception in thread "Thread-1" java.lang.IllegalMonitorStateException at java.lang.Object.notify(Native Method) at concurrency.RightLegThread.makeStep(LeftRightWaitNotifyExample.java:61) at concurrency.RightLegThread.run(LeftRightWaitNotifyExample.java:51) ``` Before I got this error when I used `wait` method non within `synchronized` block. But here I use wait within `synchronized` block What is the cause of the problem and how to fix it? update I rewrite code according advice: ``` public class LeftRightWaitNotifyExample { final static String str = "1"; public static void main(String[] args) throws InterruptedException { new LeftLegThread(str).start(); Thread.sleep(100); new RightLegThread(str).start(); } } class LeftLegThread extends Thread { String monitor; public LeftLegThread(String str) { monitor = str; } @Override public void run() { try { makeStep(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void makeStep() throws InterruptedException { synchronized (monitor) { for (int i = 0; i < 2; i++) { System.out.println("Left "); monitor.wait(); monitor.notify(); } } } } class RightLegThread extends Thread { String monitor; public RightLegThread(String str) { monitor = str; } @Override public void run() { try { makeStep(); } catch (InterruptedException e) { } } private void makeStep() throws InterruptedException { synchronized (monitor) { while (true) { System.out.println("Right "); monitor.notify(); monitor.wait(); } } } } ``` current output: ``` Left Right Left Right Right ``` Why does `Right` outs 3 but `Left` only twice. Why?

Original source