私はの行動を比較していますCompletableFuture.supplyAsyncを()で私はカスタムExecutorServiceのを設定したり、私が(指定されていない場合)私のサプライヤーは、既定のエグゼキュータによって実行されるように先の2つの場合に)(ForkJoinPool.commonPool
違いを見てみましょう:
public class MainApplication {
public static void main(final String[] args) throws ExecutionException, InterruptedException {
Supplier<String> action1 = () -> {
try {
Thread.sleep(3000);
}finally {
return "Done";
}
};
Function<String, String> action2 = (input) -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
return input + "!!";
}
};
final ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletableFuture.supplyAsync(action1, executorService)
.thenApply (action2)
.thenAccept (res -> System.out.println(res));
System.out.println("This is the end of the execution");
}
}
この場合、私は渡しているExecutorServiceのを(私のsupplyAsyncに)、それが印刷されます。
これは、実行の終わりです
完了!!
だから、「完了」メインの実行の終了後に印刷されます。
しかし、私は代わりに使用している場合:
CompletableFuture.supplyAsync(action1)
ボンネットの下に私のカスタムExecutorServiceのとCompletableFutureクラスの使用を渡さない、私はそう)ForkJoinPool.commonPool(すべてで印刷されていない「完了」:
これは、実行の終わりです
プロセスは、終了コードを終了0
どうして?
どちらの場合も、あなたが行うとき
CompletableFuture.supplyAsync(action1, executorService)
.thenApply (action2)
.thenAccept (res -> System.out.println(res));
あなたは、タスクcompletitionを待ちません。しかし、その後、あなたのプログラムを終了しようとしていると、プールに参加する方法の一般的なフォークの違いがあります:
ForkJoinPool.commonPool()
そして、通常のエグゼキュータのサービス:
final ExecutorService executorService = Executors.newFixedThreadPool(4);
同等にSystem.exitを(...)を呼び出すための試みで..react。
これは何であるドキュメントは言うフォークは共通プールに加入について、あなたはそれに注意を向ける必要があります。
しかし、このプールと進行中の処理が自動的にプログラムにSystem.exit(int型)により終了されます。プログラムの終了前に完全に非同期タスクの処理に依存している任意のプログラムが終了する前に、commonPool()。awaitQuiescenceを呼び出す必要があります。
リンクであることをExecutorServiceのドキュメントは、あなたが注意をするポイントがあります。
シャットダウン()メソッドは、以前に提出されたタスクが終了する前に実行することができます
私はそれはあなたがについて尋ね違いかもしれないと思います。