title: reason of IllegalMonitorStateException if I use wait within sync block
body: <p>I try to understand java core synchronization.</p>
  
  <p>I wrote code sample:</p>
  
  <p>Program should write </p>
  
  <blockquote>
    <p>left 
    right</p>
  </blockquote>
  
  <p>10 times</p>
  
  <pre><code>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 &lt; 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();
              }
          }
      }
  }
  </code></pre>
  
  <p>I get this output:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Before I got this error when I used <code>wait</code> method  non within <code>synchronized</code> block. But here I use wait within <code>synchronized</code> block </p>
  
  <p>What is the cause of the problem and how to fix it?</p>
  
  <h2>update</h2>
  
  <p>I rewrite code according advice:</p>
  
  <pre><code>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 &lt; 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();
              }
          }
      }
  }
  </code></pre>
  
  <p>current output:</p>
  
  <pre><code>Left 
  Right 
  Left 
  Right 
  Right 
  </code></pre>
  
  <p>Why does <code>Right</code> outs 3 but <code>Left</code> only twice. Why?</p>