如果已经完成,该方法thenRun
允许Runnable
直接在调用者的线程中执行。CompletableFuture
因为即使在像CompletableFuture.runAsync(…).thenRun(…);
这样的直接调用链中,异步任务也有可能在被调用时已经完成thenRun
,所以依赖动作有可能在调用者的线程中执行,thenRunAsync
这与总是使用默认(或提供的)执行程序不同.
所以一句话,是的,它有所作为。
顺便说一句, using thenRunAsync
(单参数版本)不会使用Executor
提供给初始工厂调用的操作执行操作,而是使用默认的Executor
.
您可以轻松比较不同的行为:
public static void main(String[] args) {
ExecutorService e=Executors.newSingleThreadExecutor(r -> new Thread(r, "sole thread"));
CompletableFuture<?> f=CompletableFuture.runAsync(()->{}, e);
f.join();
f.thenRun(()->System.out.println("thenRun:\t"+Thread.currentThread()));
f.thenRunAsync(()->System.out.println("thenRunAsync:\t"+Thread.currentThread()));
f.thenRunAsync(()->System.out.println("thenRunAsync+e:\t"+Thread.currentThread()), e);
e.shutdown();
}
将打印
thenRun: Thread[main,5,main]
thenRunAsync: Thread[ForkJoinPool.commonPool-worker-1,5,main]
thenRunAsync+e: Thread[sole thread,5,main]
然而
public static void main(String[] args) {
ExecutorService e=Executors.newSingleThreadExecutor(r -> new Thread(r, "sole thread"));
CompletableFuture<?>f=CompletableFuture.runAsync(()->LockSupport.parkNanos((int)1e9),e);
f.thenRun(()->System.out.println("thenRun:\t"+Thread.currentThread()));
f.thenRunAsync(()->System.out.println("thenRunAsync:\t"+Thread.currentThread()));
f.thenRunAsync(()->System.out.println("thenRunAsync+e:\t"+Thread.currentThread()), e);
LockSupport.parkNanos((int)2e9);
e.shutdown();
}
将打印
thenRun: Thread[sole thread,5,main]
thenRunAsync: Thread[ForkJoinPool.commonPool-worker-1,5,main]
thenRunAsync+e: Thread[sole thread,5,main]
因此thenRun
可以在调用者的线程或 的线程中执行操作,Executor
而单参数thenRunAsync
将始终使用 Fork/Join 池,并且只有两个参数thenRunAsync
将始终使用提供的执行程序。