解读Future和Promise

Future和Promise的概念早在1977年就已经提出来了。

Future是一个只读的占位符,它的值在未来某个时刻会被计算出来; Promise是一个可写的容器,可以设置Future的值 。

Future in Java

Future最早出现在Java5中,这个Future功能非常简单,只能通过轮询的方式进行查询; Google Guava中实现了ListenableFuture,提供addListener和addCallback的方式进行回调; Java8中实现了CompletableFuture,提供了比较完整的Future支持。

Java5: Future

Java5中的Future只提供了主动查询的接口,功能非常弱。

interface Future<V> {
  boolean cancel(boolean mayInterruptIfRunning);
  boolean isCancelled();
  boolean isDone();
  V get() throws InterruptedException, ExecutionException;
}

Guava: ListenableFuture

Guava的ListenableFuture继承自Future,可以通过addListener函数添加Listener。

interface ListenableFuture<V> extends Future<V> {
  void addListener(Runnable listener, Executor executor);
}

Guava还提供了一些Future的Util函数:

class Futures {
  public static <V> void addCallback(ListenableFuture<V> future,
                   FutureCallback<? super V> callback);

  public static <I,O> ListenableFuture<O> transform(ListenableFuture<I> input,
                   Function<? super I,? extends O> function);
  ...
}

Promise在Guava中对应于SettableFuture,可以通过set和setException函数设置Future的值

class SettableFuture<V> implements ListenableFuture<V> {
  public boolean set(@Nullable V value);
  public boolean setException(Throwable throwable)
}

Java8: CompletableFuture

Java8中新增了CompletableFuture,是Future和Promise的结合:

CompletableFuture还提供一些方便使用的函数:

class CompletableFuture<T> {
  public boolean complete(T value);

  public boolean completeExceptionally(Throwable ex)

  public <U> CompletableFuture<U> thenApply(Function<? super T,? extends U> fn);

  public <U,V> CompletableFuture<V> thenCombine(CompletionStage<? extends U> other,
                                BiFunction<? super T,? super U,? extends V> fn)

  public CompletableFuture<T> exceptionally(Function<Throwable,? extends T> fn)
  ...
}

Future In Scala

Scala中的Future和Promise是分开实现,提供的接口非常丰富。

trait Future[T] {
  //轮询接口
  def isCompleted: Boolean

  //回调函数接口
  def onComplete(callback: Try[T] => Unit)(implicit executor: ExecutorContext): Unit
  def onSuccess[U](pf: PartialFunction[T, U])(implicit executor: ExecutionContext): Unit
  def onFailure[U](pf: PartialFunction[Throwable, U])(implicit executor: ExecutionContext): Unit

  //andThen接口
  def andThen[U](pf: PartialFunction[Try[T], U])(implicit executor: ExecutionContext): Future[T]

  //transform接口
  def filter(p: T => Boolean): Future[T]
  def flatMap[U](f: T => Future[S]): Future[S]
  def map[U](f: T => U): Future[U]

  //错误处理接口
  def recoverWith(f: PartialFunction[Throwable, Future[T]]): Future[T]
}

trait Promise {
  def future: Future[T]

  def complete(result: Try[T]): Unit
  def tryComplete(result: Try[T]): Boolean
  def success(value: T): Unit
  def failure(t: Throwable): Unit
}

Future In C++11

C++11中的future非常简单,和java5中的Future类似,只能轮询或者阻塞等待,没有提供回调函数:

template<class T> class future {
  T get();
  bool valid() const;
  void wait() const;
  ...
}

C++11中的promise比较完整(因为promise本身比较简单):

template< class R > class promise {
  std::future<T> get_future();
  void set_value( const R& value );
  void set_exception( std::exception_ptr p );
  ...
}

References

Written on March 7, 2018