がすでに完了している場合、このメソッドを使用すると、呼び出し元のスレッドで直接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]
一方
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 プールを使用し、2 つの引数のみthenRunAsync
が提供されたエグゼキューターを常に使用します。