並行性が問題であるが、大幅に簡略化強力な単純な抽象の使用を介してであってもよい、問題を簡単にするために、グアバは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を変換します。
綿密な調査
元は容易ではない、ソースを明記してください。