title: IllegalMonitorStateException thrown in synchronized(lock){lock.notify();} ... why?
body: <p>I'm debugging an Android service written by one of our previous developers, and he's used a <code>Boolean</code> in the following way:</p>
  
  <pre><code>public static class DownloadQueue extends LinkedHashMap  
  {
      // ...
      private Boolean lock = new Boolean(false);
      // ...
  
      //typical notify use
      synchronized public Object addToHead(Object key, Object value)
      {
          // ...
          synchronized (lock) 
          {
              //IllegalMonitorStateException FROM HERE
              lock.notify();
          }
          // ...
          return null;
      }
  
      //queue machinery
      public DownloadRecord getFirst()
      {
          // we block because queue is empty
          if(this.size() == 0 || (MyApp.isInternetConnectionAvailable() == false))
          {
              try 
              {   
                  lock = true;
                  synchronized (lock) 
                  {
                      lock.wait(30000);
                  }
                  lock = false;
              }
              catch (InterruptedException e) 
              {}
          //continue operating the queue
          // ...
          return value;
      }
  }
  </code></pre>
  
  <p>The documentation I've found on <code>IllegalMonitorStateException</code> suggests it's caused by not calling <code>notify()</code> from a <code>synchronized</code> block; however, that is clearly not the case here.  I did wonder if the scope of <code>lock</code> might be a problem, or whether the unsynchronized assignments could be.  All the references to <code>lock</code> are of the form above, with just the one <code>wait(long)</code> in the queue function.</p>
  
  <p>One final, possibly useful detail: this is occurring because, although our device has network, our CMS is down.  We're taking the opportunity to test the app in this condition.  I suspect the queue might be operating at breakneck speed because failed downloads are getting requeued, so if a race condition is a possible cause of this fault, then it may be the cause here.</p>
  
  <p>Thanks!</p>