code: @Override
      public void release() throws Exception
      {
          /*
              Note on concurrency: a given lockData instance
              can be only acted on by a single thread so locking isn't necessary
           */
  
          Thread currentThread = Thread.currentThread();
          LockData lockData = threadData.get(currentThread);
          if ( lockData == null )
          {
              throw new IllegalMonitorStateException("You do not own the lock: " + basePath);
          }
  
          int newLockCount = lockData.lockCount.decrementAndGet();
          if ( newLockCount > 0 )
          {
              return;
          }
          if ( newLockCount < 0 )
          {
              throw new IllegalMonitorStateException("Lock count has gone negative for lock: " + basePath);
          }
          try
          {
              internals.releaseLock(lockData.lockPath);
          }
          finally
          {
              threadData.remove(currentThread);
          }
      }
docs: Perform one release of the mutex if the calling thread is the same thread that acquired it. If the
  thread had made multiple calls to acquire, the mutex will still be held when this method returns.
  
  @throws Exception ZK errors, interruptions, current thread does not own the lock