JAva 8のCompletableFuture


とても良いブログを参考にしてここをスタンプします

一、背景


JDK1.5ではスレッドの取得結果を大きく最適化しており、具体的には私の以前のブログスタンプを参考にすることができますが、マルチスレッドの結果に対しては無限ループやブロック方式で取得されており、Rxjavaはすでに観察者モードを利用して実現しており、完了後にコールバックで結果を取得しています.だからjdk 1.8にクラスCompletableFutureを追加し、Futureを強化します.

二、簡単で実用的


2.1、非同期アプリケーションの作成

CompletableFuture.supplyAsync(()->{
            sleep(60000);
            System.out.println(" :"+Thread.currentThread().getName()+" supplyAsync");
            return "zhw";
 })

関数式プログラミングを用いて実現または比較的簡単で明瞭である.supplyAsync内部にスレッドプールが自動的に作成されます.もちろん、スレッドプールを指定できます.
デフォルトのスレッドプールのコードは次のとおりです.
/**
     * Default executor -- ForkJoinPool.commonPool() unless it cannot
     * support parallelism.
     */
    private static final Executor asyncPool = useCommonPool ?
        ForkJoinPool.commonPool() : new ThreadPerTaskExecutor();

jdk 1を利用する.7のForkJoinPoolスレッドプールでは、リレーショナルスレッドプールの作成や破棄を必要とせず、特定のビジネスに関係するだけで開発効率が向上します.
runAsynは作成も完了できますが、パラメータが異なるのはsupplyAsyncのほうが実用的です.
public static CompletableFuture 	runAsync(Runnable runnable)
public static CompletableFuture 	runAsync(Runnable runnable, Executor executor)

特徴:
  • Asyncで終わる方法であれば、いずれも別の新しいスレッドが非同期で実行されます.それ以外の場合は、前の呼び出しと同じスレッドで実行され、ほとんどのメソッドに適用されます.次のApply、Accept、whenCompleteメソッドなど
  • が必要です.

    2.2、Apply結果の更なる処理


    supplyAsyncメソッドとCompletableFutureの多くは、チェーン呼び出しの基礎となる新しいCompletableFuture参照を返します.
     CompletableFuture.supplyAsync(()->{
                sleep(60000);
                System.out.println(" :"+Thread.currentThread().getName()+" supplyAsync");
                return "zhw";
            }).thenApplyAsync(x->{
                System.out.println(" :"+Thread.currentThread().getName()+" thenApply");
                return x+" hellow word";
            });
    

    例えばthenApplyAsyncでは、この方法は字面から別のスレッドを見て、thenApplyは同期呼び出しです.上記のapplyの方法は、上記の結果をパラメータとして利用する、supplyAsyncが「zhw」を返し、thenApplyAsync法で「zhw」がパラメータとして伝達されるなど、結果を再処理する加工である.
    以下は私のまとめです
    CompletableFutureでのメソッド
    関数インタフェース
    Apply
    Function

    2.3、Accept対結果純消費


    彼とApplyの方法の違いはconsumerを更新することです
    CompletableFutureでのメソッド
    関数インタフェース
    Apply
    Consumer
    前のチェーン式の結果はApply,acceptメソッドのパラメータです.

    2.4、whenComplete取得結果

      public static void testWhenComplete() throws Exception{
    
            CompletableFuture future = CompletableFuture.supplyAsync(BasicMain::getMoreData);
            Future f = future.whenComplete((v, e) -> {
                System.out.println(v);
                System.out.println(e);
            });
            System.out.println(f.get());
        }
    

    whenCompleteには2つのパラメータがあり、1つ目は正常な結果で、2つ目は異常です.中にはhandleメソッドもありますが、これは実はwhenComplete+Apply、2つのメソッドの組み合わせです

    2.5、結果連合


    2つのやりたくないメソッド呼び出しは、同時に開始し、2つの結果をマージして返すことができます.
     CompletableFuture
                    .supplyAsync(()->{
                        log.debug("supplyAsync1");
                        sleep(2000);
                        return "zhw";
                    })
                    .thenCombineAsync(CompletableFuture.supplyAsync(()->{
                        log.debug("supplyAsync2");
                        sleep(2000);
                        return " hellow ";
                    }),(s1,s2)->{
                        log.debug("thenCombineAsync");
                        return s1+s2;
                    })
    

    例えば、上記の2つの方法はそれぞれ2 sを必要とし、同期処理が4 sで終了する必要がある場合、処理後2 sだけで結果を返す.現在も2つの結果が結合しているのを見ているだけで、まだ制限があるような気がしますが、Rxjavaほど便利ではありません.