質問: CompletableFuture.supplyAsync( () -> { // 時間のかかる処理 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return "java1"; }); // thenApplyの場合 future1 .thenApply( new Function() { @Override public String apply(String res) { return res; // resには、future1のreturnで定義した「java1」が入っている } }) .thenApply( res -> { return res; // resには1回目のthenApplyの戻り値の「java1」が入っている }) .thenAccept( new Consumer() { @Override public void accept(String res) { System.out.println(res); // resには2回目のthenApplyの戻り値の「java1」が入っており、コンソールに出力される } }); } } ``` ちなみにThread.sleep(1000);をThread.sleep(1);のように短くしたり、コメントアウトするとコンソール出力されます。動きとして、1秒後に返される戻り値を待てずにthenApply以降の処理が実行されているのかなと思います。 thenApply自体は前の処理の完了は待たないのでしょうか?「このステージが正常に完了したときに、このステージの結果を指定された関数への引数に設定して実行される新しいCompletionStageを返す。」だけであって。すなわち次の処理が同期処理になるだけでしょうか? またもしそうだとした場合、著者の方はsleep処理を入れたと予想できますでしょうか?まるで1秒待ってから次の処理が実行されるようなリードですが。 もしわかる方がいればよろしくお願いいたします。
回答: こちらの回答 * 非同期処理において結果が思ったように出ない理由を知りたい に記載した理由と同じです。 `Executor`を引数に取らない`CompletableFuture.supplyAsync()`)で得られたfutureは**デーモンスレッド**で処理されます。 ですのでメインスレッドが終了するとこのスレッドも終了します。 が、そのタイミングで`future1`が完了しているとは限りません。 (完了していなければ、当然、`thenApply()` 以降も実行されません。) > > thenApply自体は前の処理の完了は待たないのでしょうか? > > > 待ちます。 ただし、今回の場合、そもそもその「前の処理」が完了しないうちにプロセスが終了しています。 なお、このデーモンスレッドがどうこうというのは`CompletableFuture`の本質には関係がないので、とりあえずこのようなサンプルコードを試す際には(この回答のように)`main`メソッドの最後に少し長めにスリープを入れる、としておけば`CompletableFuture`の学習に集中できるかと思います。 (参照されているようなコードサンプルでは、プロセスの生存期間は`CompletableFuture`実行時間に対して十分長いことが前提になっていると思います。)