title: Multithreading in java (two threads extensively using both notify() and wait())
body: <p>When I try to run a following program, there is an IllegalMonitorStateException in the first call to notify () in this piece of code:</p>
  
  <pre><code>synchronized (c) {
      try {
          notify();
          ....
  </code></pre>
  
  <p>This throws me off a little bit: how is it possible for the code not to have a lock on an object (c) when it is already in the synchronized block, that checks for the same lock?</p>
  
  <p>Please do not mind somewhat odd-looking overuse of notify() and wait(). I know there are different (and more efficient) implementations available which perform the same task, but right now I am trying to figure out why this particular one does not work.</p>
  
  <p>The full code is as follows:</p>
  
  <pre><code>  class J implements Runnable {
  
          public static void main(String[] x) {
              Calc calc = new Calc();
              J j = new J(calc);
              Thread t1 = new Thread(j, "one");
              Thread tCalc = new Thread(calc, "Calc");
              tCalc.start();
              t1.start();
          }
          Calc c;
          public J(Calc c) {
              this.c = c;
          }
  
          public void run() {
              synchronized (c) {
                  try {
                      notify();
                      c.wait();
                  } catch (InterruptedException e) {
  
                  }
                  System.out.println(Thread.currentThread().getName() + ": x = "
                          + c.getX());
                  notify();
              }
          }
      }
  
      class Calc implements Runnable {
  
          private int x;
  
          public int getX() {
              return x;
          }
  
          public void run() {
              synchronized (this) {
  
                  for (int x = 1; x &lt;= 11111; x *= (x + x)) {
                      this.x += x;
                      try {
                          notify();
                          this.wait();
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                  notify();
              }
          }
      }
  </code></pre>