code: @CanIgnoreReturnValue
    @Override
    public V get() throws InterruptedException, ExecutionException {
      if (Thread.interrupted()) {
        throw new InterruptedException();
      }
      Object localValue = value;
      if (localValue != null & !(localValue instanceof SetFuture)) {
        return getDoneValue(localValue);
      }
      Waiter oldHead = waiters;
      if (oldHead != Waiter.TOMBSTONE) {
        Waiter node = new Waiter();
        do {
          node.setNext(oldHead);
          if (ATOMIC_HELPER.casWaiters(this, oldHead, node)) {
            // we are on the stack, now wait for completion.
            while (true) {
              LockSupport.park(this);
              // Check interruption first, if we woke up due to interruption we need to honor that.
              if (Thread.interrupted()) {
                removeWaiter(node);
                throw new InterruptedException();
              }
              // Otherwise re-read and check doneness. If we loop then it must have been a spurious
              // wakeup
              localValue = value;
              if (localValue != null & !(localValue instanceof SetFuture)) {
                return getDoneValue(localValue);
              }
            }
          }
          oldHead = waiters; // re-read and loop.
        } while (oldHead != Waiter.TOMBSTONE);
      }
      // re-read value, if we get here then we must have observed a TOMBSTONE while trying to add a
      // waiter.
      return getDoneValue(value);
    }
docs: {@inheritDoc}
  
  <p>The default {@link AbstractFuture} implementation throws {@code InterruptedException} if the
  current thread is interrupted during the call, even if the value is already available.
  
  @throws CancellationException {@inheritDoc}