0318グアバ並行処理ユーティリティ

image.png


並行性が問題であるが、大幅に簡略化強力な単純な抽象の使用を介してであってもよい、問題を簡単にするために、グアバはListenableFutureは(未来を聞くことができる)、将来のインターフェースを拡張します。
私は強くあなたが次のような理由から、将来を置き換えるために、すべてのコードListenableFutureを使用することをお勧めします:

  • 多くの方法先物クラスは、それを必要とします。(使用に先物ツール)
  • これは、後で変換よりListenableFutrue簡単です。(以前の再構成より使いやすいです)
  • それは法と今後のバリアントListenableFutureの方法を提供するために必要なツールを提供しています。(あなたは、二組の互換性は必要ありません)

インターフェース

従来の非同期Futrueは、計算の結果を表す:完了または出力の計算を完了してもしなくてもよいです。
今後の進展が計算に使用される、またはサービスを提供する当社の取り組みの結果であることができます。

ListenableFutureあなたは計算に仕上がったときにコールバックを登録することができ、または計算が完了しています。
この単純な拡張機能が効率的に複数のオペレーティングをサポートすることを可能にします。今後のインタフェースがサポートされていません。

追加基本動作ListenbleFutureである
のaddListener(Runnableを、執行)、
次の計算が完了したときを示し、指定されたエグゼキュータに指定Runnable実行。

増加のコールバック

多くのユーザーはFutures.addCallback(ListenableFuture、FutureCallback、エグゼキュータ)メソッドを使用することを好みます。
FutureCallbackは、次の2つの方法を達成しました:

  • するonSuccess計算結果に基づいて、将来の行動の(v)の実装を成功さ、
  • 失敗に基づいてONFAILURE(Throwableの)アクションが未来を実行するために失敗し、

作ります

ExecutorService.submit(呼び出し可能)と比較して、JDK非同期計算を初期化する方法を提供します。これは、定期的な未来を返し
グアバはListenableFutureを返すListeningExecutorServiceインタフェースを提供します。
コンバートListenableExecutorServiceのにExecutorServiceの
使用:MoreExecutors.listeningDecorator(ExecutorServiceの)

次のように基本的な使い方は次のとおりです。


/**
 * 说明:使用例子代码
 * @author carter
 * 创建时间: 2020年03月19日 9:54 上午
 **/

@Slf4j
public class ListenableFutureUtils {

    public static void main(String[] args) {

ListeningExecutorService service = MoreExecutors.listeningDecorator(
    Executors.newFixedThreadPool(10));


        final ListenableFuture<AResult> listenableFuture = service.submit(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return new AResult(30, "male", 1);

        });


        Futures.addCallback(listenableFuture,
                new FutureCallback<AResult>() {
                    @Override
                    public void onSuccess(AResult aResult) {
                        log.info("计算成功,{}",aResult);
                    }

                    @Override
                    public void onFailure(Throwable throwable) {

                        log.error("计算错误",throwable);

                    }
                },service);

    }

    @Data
    @AllArgsConstructor
    public static class AResult{

        private Integer age;

        private String sex;

        private Integer id;


    }

}复制代码

あなたはオーバーAPIベースのFutureTaskから変換したい場合はこれとは対照的に、
グアバの提供
ListenableFutureTask.create(コーラブル)

ListenableFutureTask.create(Runnableを)は
JDKとは異なり、ListenableFutureTaskは直接拡張されません。

あなたは抽象的なセットの将来の値を好きなら、ではなく、法と計算値を実装AbstractFutureまたは使用SettableFutureを使用することを検討してください。 

あなたが未来のListenableFutureを変換する必要がある場合は、選択肢がない、あなたが使用する必要があります将来はListenableFutureで変換することJdkFutureAdapters.listenInPoolThread(将来の)
可能な限り、あなたがListenableFutureを返すためにソースコードを変更することをお勧めします

アプリケーション

ListenablFuture最も重要なことを使用する理由は、チェーン非同期操作を使用することです。

コードは以下の通りであります:

package com.xxx.demo;

import com.google.common.util.concurrent.AsyncFunction;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * 说明:异步操作链
 * @author carter
 * 创建时间: 2020年03月19日 10:11 上午
 **/

public class ApplicationUtils {


    public static void main(String[] args) {

        Query query = new Query(30);

        ListenableFuture<RowKey> rowKeyFuture = lookUp(query);

        AsyncFunction<RowKey, QueryResult> queryFun = rowKey -> readData(rowKey);

        final ListenableFuture<QueryResult> queryResultListenableFuture = 
            Futures.transformAsync(rowKeyFuture, queryFun);

    }

    private static ListenableFuture<QueryResult> readData(RowKey rowKey) {
        return null;
    }

    private static ListenableFuture<RowKey> lookUp(Query query) {
        return null;
    }


    @Data
    @AllArgsConstructor
    public static class RowKey {

        private String id;

    }

    @Data
    @AllArgsConstructor
    public static class Query {

        private Integer age;

    }


    @Data
    @AllArgsConstructor
    public static class QueryResult {

        private String id;
        private String age;

    }


}
复制代码

今後は提供されていない間、他の多くのサポートされているオペレーティングListenableFutureは、効率的に提供しています。
異なる操作が異なるスレッドプールで実行することができ、簡単なのListenableFutureは待つように複数の操作を持つことができます。

長い操作を始めたように、他の操作の数は、ファンアウトを開始する必要があり、千枚の帆を競います。

ListenableFutureは、このような動作を実現することができます:それはすべての要求のためのコールバックをトリガします。

少しの仕事は、私たちファンインすることができます。

その結果、将来のもう一方の端を取得するListenableFutureトリガー。

Futures.allAsListはその一例です。

方法はじめに:

方法 説明
transformAsync(ListenableFuture、AsyncFunction、エグゼキュータ) 新しいListenableFutureを返し、結果がリターン非同期関数で、関数が結果パラメータがListenableFutureで返します。
変換(ListenableFuture、機能、エグゼキュータ) 新しいListenableFutureを返し、それは、関数の実行結果を返す、関数が結果パラメータがListenableFutureで返します。
allAsList(反復処理可能 戻りListenableFuture、その結果は、各リストのListenableFuture実行結果を含むリストである、ListenableFuture実行するかキャンセルする任意の障害は、最終的なリターンの結果を取り消します
successfullAsList(反復処理可能 その結果がリストである戻りListenableFuture、各リストのListenableFuture実行結果を含む、成功の結果である、または代替ヌルの使用の値をキャンセルする障害

AsyncFunction <A、B>は方法を提供し、ListenableFutureは非同期の値を変換するために使用することができる(inpunt)を適用します。

コードは以下の通りであります:

package com.xxx.demo;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * 说明:成功执行结果汇集
 * @author carter
 * 创建时间: 2020年03月19日 10:34 上午
 **/
@Slf4j
public class Test3 {

    public static void main(String[] args) {

        List<ListenableFuture<QueryResult>> querys = Lists.newLinkedList();
        final ListenableFuture<List<QueryResult>> successfulAsList =
            Futures.successfulAsList(querys);

        Futures.addCallback(successfulAsList, new FutureCallback<List<QueryResult>>() {
            @Override
            public void onSuccess(List<QueryResult> queryResults) {
                log.info("执行结果列表:{}",queryResults);
            }

            @Override
            public void onFailure(Throwable throwable) {
                log.error("执行失败",throwable);
            }
        });


    }

    @Data
    @AllArgsConstructor
    public static class QueryResult{


      private  Integer age;

    }


}
复制代码

ネストされた未来

あなたのコードは共通のインターフェースを呼び出すと未来を返し、そう最終的にネストされた未来を返すことです。

package com.xxx.demo;

import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;

/**
 * 说明:嵌套的ListenableFuture
 * @author carter
 * 创建时间: 2020年03月19日 10:43 上午
 **/

public class Test4 {

    public static void main(String[] args) {


        final ListeningExecutorService executorService = MoreExecutors
            .listeningDecorator(Executors.newFixedThreadPool(2));
        final ListeningExecutorService otherExecutorService = MoreExecutors
            .listeningDecorator(Executors.newFixedThreadPool(2));


        Callable<Foo> otherCallback =  ()->new Foo("aaa");


        final ListenableFuture<ListenableFuture<Foo>> submit = 
                executorService.submit(() -> otherExecutorService.submit(otherCallback));


    }

    @Data
    @AllArgsConstructor
    public static class Foo{

        private String name;
    }

}
复制代码

最後のリターンの例:ListenableFuture <ListenableFuture >
今後の外層がキャンセルされた場合、将来の内層に広がっできないため、このコードは、間違っている
、また、エラーListnenerの利用GET()ルーチン検査や他の未来であります

しかし、特に断りのない限りotherCallback特別な注意スローされた例外は抑制されます。
このような状況、グアバのすべての今後の治療(JDKの一部)を回避するために、巣のセキュリティロックを解除するために非同期バージョンが*。

比如:submitAsync方法、提出、transformAsynを変換します。

綿密な調査

元は容易ではない、ソースを明記してください。

おすすめ

転載: juejin.im/post/5e73085fe51d45271b748eca