code: public void waitForCompletion(long timeout) throws AsyncTimeoutException, InterruptedException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
              Tr.debug(tc, "waitForCompletion: " + timeout);
          }
  
          // First do a non-sync test, to see if we can return quickly
          if (this.fullyCompleted) {
              return;
          }
  
          synchronized (this.completedSemaphore) {
              if (this.completed) {
                  return;
              }
              // not completed, so we must wait to be notified of completion.
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "waiting for completion notification for future: " + this);
              }
              this.completedSemaphore.wait(timeout);
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "done waiting for completion notification for future: " + this);
              }
          } // end-sync
  
          // we either woke up because the operation completed, or timed out.
          // For performance reasons, first do a lazy check to see if we are done.
          // If we are not then grab the semaphore, and throw a timed out
          // exception.
          if (this.fullyCompleted) {
              return;
          }
  
          synchronized (this.completedSemaphore) {
              if (!this.completed) {
                  this.completed = true;
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "Sync operation timed out");
                  }
                  throw new AsyncTimeoutException();
              }
          } // end-sync
      }
docs: Blocks the calling thread until either the Future has completed or the
  timeout period has expired. The timeout period is set in milliseconds.
  
  @param timeout
  the maximum time to wait in milliseconds.
  Specifying 0L means wait forever.
  @throws AsyncTimeoutException
  if the timeout period elapsed.
  @throws InterruptedException
  if the waiting thread is interrupted before
  the wait completes.