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

时间:2016-04-06 21:34:03

标签: java java-8 completable-future

在以下代码中,调用 thenRunAsync 会有什么不同吗?我应该只是打电话给 thenRun 吗?

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

回应评论时的阐述:如果我改为使用此代码,

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

会有什么不同吗?

在这两种情况下,行为都是无阻塞的,无论如何,第二项任务不会在第一项任务完成之前运行,据我所知。

1 个答案:

答案 0 :(得分:9)

如果thenRun已经完成,方法Runnable允许直接在调用者的线程中执行CompletableFuture。因为即使在像CompletableFuture.runAsync(…).thenRun(…);这样的直接调用链中,异步任务可能在调用thenRun时已经完成,也可能在调用者的线程中执行相关操作,这与{ {1}}将始终使用默认(或提供的)执行程序。

所以在一句话中,是的,它会产生影响。

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

将打印

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将始终使用Fork / Join池,并且只使用两个参数thenRunAsync将始终使用提供的执行程序。