Musso & Frank Grill

各種非同步 對照

Andrew Chen
2 min readDec 20, 2017
  • Thread + Runnable
  • Guava: ListenableFuture
  • Java8: CompletableFuture
  • Rxjava: Observable / Completable
  • Android: AsyncTask

Thread + Runnable

new Thread(() -> {}).start()

等到完成:

Thread thread = new Thread(() -> {});
thread.start();
thread.join(); // 等待 thread 完成

我們可以生個 HandlerRunnable 內,達到通知的效果。

使用特色 Executor 以便控制 Thread pool 策略:

Future<V> Executors.newSingleThreadExecutor().submit(() -> null);

Guava ListenableFuture:

Executor executor = Executors.newSingleThreadExecutor()
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(executor);
ListenableFuture<Void> future = executorService.submit(() -> null);
Futures.addCallback(future, v -> {}, e -> {}, executor); // pseudo

Java8 CompletableFuture:

CompletableFuture future = CompletableFuture.runAsync(() -> {}, executor);
future.whenComplete(() -> {}, e -> {})

RxJava Observable / Completable:

Completable.fromRunnable(() -> {}).subscribe(() -> {}, e -> {});
Completable.fromFuture(future).subscribe(() -> {}, e -> {});

轉換 Future -> ListenableFuture / CompletableFuture / Observable

CompletableFuture

最簡單的方式是:

public static <T> CompletableFuture<T> completableFuture(Future<T> future) {
return CompletableFuture.supplyAsync(() -> {
try {
return future.get();
} catch (InterruptedException|ExecutionException e) {
throw new RuntimeException(e);
}
});
}

但是這會有阻塞的問題,那個要給怎樣的 thread pool 又是一個問題,需要留意一下。

ListenableFuture

ListenableFuture<T> listenInPoolThread(future, executor)

接龍 / 鏈式(Chaining and Transforming)

p.s. 一般的 Thread / Executor + Runnable 或者 Future 都不支援串接轉換。

Guava ListenableFuture:

ListenableFuture<String> Futures.transform(future, v -> String.valueOf(v), executor);

Java8 CompletableFuture:

future.thenApply(v -> String.valueOf(v));

RxJava Observable / Completable:

Observable.map(v -> String.valueOf(v)).subscribe(v -> {}, e -> {});

轉成 RxJava

Guava ListenableFuture:

Single<Void> single = FutureConverter.toSingle(listenable);
Completable completable = single.toCompletable();
completable.subscribe(() -> {}, e -> {});

Java8 CompletableFuture:

Completable completable = CompletableInterop.fromFuture(future);
completable.subscribe(() -> {}, e -> {});

Kotlin coroutine:

launch {
}

See Also

  • CountDownLatch
  • executor.shotdown()

References

--

--