code: public LockResult lock(
        final TaskLockType lockType,
        final Task task,
        final Interval interval,
        long timeoutMs
    ) throws InterruptedException
    {
      long nanos = TimeUnit.MILLISECONDS.toNanos(timeoutMs);
      giant.lockInterruptibly();
      try {
        LockResult lockResult;
        while (!(lockResult = tryLock(lockType, task, interval)).isOk()) {
          if (nanos <= 0 || lockResult.isRevoked()) {
            return lockResult;
          }
          nanos = lockReleaseCondition.awaitNanos(nanos);
        }
        return lockResult;
      }
      finally {
        giant.unlock();
      }
    }
docs: Acquires a lock on behalf of a task, waiting up to the specified wait time if necessary.
  
  @param lockType  lock type
  @param task      task to acquire a lock for
  @param interval  interval to lock
  @param timeoutMs maximum time to wait
  
  @return {@link LockResult} containing a new or an existing lock if succeeded. Otherwise, {@link LockResult} with a
  {@link LockResult#revoked} flag.
  
  @throws InterruptedException if the current thread is interrupted