code: @Override
      public V get() throws InterruptedException, ExecutionException {
          synchronized (lock) {
              if (value != null) {
                  return value;
              }
              lock.wait();
  
              if (value != null) {
                  return value;
              }
  
              if (throwable != null) {
                  throw new ExecutionException(throwable);
              }
              throw new ExecutionException(new FatalImplementationErrorException("Not terminated after notification!", this));
          }
      }
docs: Method blocks until the future is done. The method return the result if the future was normally completed.
  If the future was exceptionally completed or canceled an exception is thrown.
  
  @return the result of the task.
  
  @throws InterruptedException is thrown if the thread was externally interrupted.
  @throws ExecutionException   is thrown if the task was canceled or exceptionally completed.