if (currentWriter == null) { numReaders --; if (numReaders == 0 && numWritersWaiting != 0) documentCV.notify(); } }
numReaders--; notify();
  public final void readUnlock()  {    // Note we could have a problem here if readUnlock was called without a    // prior call to readLock but the specs simply warn users to ensure that    // balance by using a finally block:    // readLock()    // try    // {     //   doSomethingHere     // }    // finally    // {    //   readUnlock();    // }        // All that the JDK seems to check for is that you don't call unlock    // more times than you've previously called lock, but it doesn't make    // sure that the threads calling unlock were the same ones that called lock    // If the current thread holds the write lock, and attempted to also obtain    // a readLock, then numReaders hasn't been incremented and we don't need    // to unlock it here.    if (currentWriter == Thread.currentThread())      return;    // FIXME: the reference implementation throws a     // javax.swing.text.StateInvariantError here    if (numReaders == 0)      throw new IllegalStateException("document lock failure");        synchronized (documentCV)    {      // If currentWriter is not null, the application code probably had a       // writeLock and then tried to obtain a readLock, in which case       // numReaders wasn't incremented      if (currentWriter == null)        {          numReaders --;          if (numReaders == 0 && numWritersWaiting != 0)            documentCV.notify();        }    }  }