如果在 runAsync 调用之后链接,那么 thenRunAsync(与 thenRun 相对)是否有任何区别?

2024-03-10

在下面的代码中,调用有什么区别吗thenRunAsync?我应该打电话吗thenRun反而?

CompletableFuture.runAsync(this::doWork , executorService)
     .thenRunAsync(this::handleSuccess);

详细说明回应评论:如果我要使用这段代码,

CompletableFuture.runAsync(this::doWork , executorService)
     .thenRun(this::handleSuccess);

它的行为会有什么不同吗?

在这两种情况下,行为都是非阻塞的,并且据我了解,第二个任务在第一个任务完成之前不会运行。


方法thenRun允许执行Runnable直接在调用者的线程中,如果CompletableFuture已经完成了。因为即使在像这样的直接调用链中CompletableFuture.runAsync(…).thenRun(…);此时异步任务有可能已经完成thenRun被调用时,依赖操作有可能在调用者的线程中执行,这与thenRunAsync它将始终使用默认(或提供的)执行器。

所以用一句话来说,是的,这会有所不同。


顺便说一下,使用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]

whereas

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]

So thenRun可以在调用者的线程或Executor的线程,而单一参数thenRunAsync将始终使用 Fork/Join 池并且仅使用两个参数thenRunAsync将始终使用提供的执行器。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果在 runAsync 调用之后链接,那么 thenRunAsync(与 thenRun 相对)是否有任何区别? 的相关文章

随机推荐