code: public static <V, E extends Exception> Optional<V> tryGetFutureValue(Future<V> future, int timeout, TimeUnit timeUnit, Class<E> exceptionType)
              throws E
      {
          requireNonNull(future, "future is null");
          checkArgument(timeout >= 0, "timeout is negative");
          requireNonNull(timeUnit, "timeUnit is null");
          requireNonNull(exceptionType, "exceptionType is null");
  
          try {
              return Optional.ofNullable(future.get(timeout, timeUnit));
          }
          catch (InterruptedException e) {
              Thread.currentThread().interrupt();
              throw new RuntimeException("interrupted", e);
          }
          catch (ExecutionException e) {
              Throwable cause = e.getCause() == null ? e : e.getCause();
              propagateIfPossible(cause, exceptionType);
              throw new RuntimeException(cause);
          }
          catch (TimeoutException expected) {
              // expected
          }
          return Optional.empty();
      }
docs: Waits for the the value from the future for the specified time.  If the future
  value is null, an empty Optional is still returned, and in this case the caller
  must check the future directly for the null value.  If the future is failed,
  the exception is thrown directly if it is an instance of the specified exception
  type or unchecked, or it is wrapped in a RuntimeException. If the thread is
  interrupted, the thread interruption flag is set and the original
  InterruptedException is wrapped in a RuntimeException and thrown.