public boolean releaseExclusiveLock(Procedure<?> proc) {
    if (
      exclusiveLockOwnerProcedure == null
        || exclusiveLockOwnerProcedure.getProcId() != proc.getProcId()
    ) {
      // We are not the lock owner, it is probably inherited from the parent procedures.
      return false;
    }
    exclusiveLockOwnerProcedure = null;
    // This maybe a bit strange so let me explain. We allow acquiring shared lock while the parent
    // proc or we have already held the xlock, and also allow releasing the locks in any order, so
    // it could happen that the xlock is released but there are still some procs holding the shared
    // lock.
    // In HBase, this could happen when a proc which holdLock is false and schedules sub procs which
    // acquire the shared lock on the same lock. This is because we will schedule the sub proces
    // before releasing the lock, so the sub procs could call acquire lock before we releasing the
    // xlock.
    return sharedLock == 0;
  }
Returns whether we should wake the procedures waiting on the lock here.
hbase-procedure/src/main/java/org/apache/hadoop/hbase/procedure2/LockAndQueue.java