5.1 ListenableFuture:完了後にコールバックをトリガーするFuture
6063 ワード
Google GuavaパッケージのListenableFuture解析
羅立樹校正:方騰飛
コンカレントプログラミングネットワークから転載-ifeve.com本文リンクアドレス:google GuavaパッケージのListenableFuture解析
同時プログラミングは難題であるが,強力で簡単な抽象は同時作成を著しく簡略化することができる.このような考えから、GuavaはListenableFutureインタフェースを定義し、JDK concurrentパッケージの下のFutureインタフェースを継承する.
JDKのFutureの代わりにListenableFutureをコードに多く使用することを強くお勧めします.
ほとんどのFuturesメソッドでは必要です.
ListenableFutureプログラミングに移動するのは簡単です.
Guavaが提供する汎用共通クラスは共通のオペレータメソッドをカプセル化し,FutureとListenableFutureの拡張メソッドを提供する必要はない.
インタフェース
従来のJDKのFutureは、非同期的に戻り結果を計算します.マルチスレッド演算では、戻り結果が終了しない可能性があります.Futureは、サービス実行中のマルチスレッドの参照ハンドルであり、サービス実行中にResultが返されることを保証します.
ListenableFutureでは、コールバックメソッド(callbacks)を登録し、演算(マルチスレッド実行)が完了したときに呼び出すか、演算(マルチスレッド実行)が完了した直後に実行することができます.このような簡単な改良により、より多くの操作を明らかにサポートすることができ、このような機能はJDK concurrentのFutureではサポートされていない.
ListenableFutureの基本手法はaddListener(Runnable,Executor)であり,マルチスレッド演算が完了すると,指定したRunnableパラメータが入力されたオブジェクトが指定したExecutorによって実行される.
コールバックの追加(Callbacks)
多くのユーザーはFuturesを使うのが好きだ.addCallback(ListenableFuture,FutureCallback,Executor)の方式、または別のバージョンversion(訳者注:addCallback(ListenableFuture future,FutureCallback super V>callback))は、デフォルトではMoreExecutorsが採用する.sameThreadExecutor()スレッドプールは、使いやすくするためにCallbackは軽量級の設計を採用している.FutureCallbackでは、次の2つの方法が実装されています.
onSuccess(V)は、Futureが成功したときに実行し、Futureの結果から判断します.
onFailure(Throwable)は、Futureが失敗したときに実行し、Futureの結果から判断します.
ListenableFutureの作成
JDKのExecutorServicesに対応する.submit(Callable)がマルチスレッド非同期演算をコミットする方式で、GuavaはListeningExecutorServiceインタフェースを提供し、このインタフェースはListenableFutureを返し、対応するExecutorServiceは通常のFutureを返す.ExecutorServiceからListeningExecutorServiceに移行するにはMoreExecutorsを使用します.ListeningDecorator(ExecutorService)が装飾しています.ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture explosion = service.submit(new Callable() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
また、FutureTaskから変換された場合、GuavaはListenableFutureTaskを提供します.CallableとListenableFutureTask.create(Runnable, V). JDKとは異なりListenableFutureTaskは勝手に継承できない(ListenableFutureTaskのdoneメソッドはlistenerを呼び出す操作を実現している).
インタフェースのメソッドではなく、抽象的な方法でfutureの値を設定するのが好きな場合は、抽象クラスAbstractFutureを継承するか、SettableFutureを直接使用することを考慮します.
他のAPIが提供するFutureをListenableFutureに変換する必要がある場合は、ハードコーディングしかできない方法はありません.ListenInPoolThread(Future)は、FutureをListenableFutureに変換します.可能な限りオリジナルのコードを修正してListenableFutureに戻るほうがいいです.
Application
ListenableFutureを使用する最も重要な理由は、一連の複雑なチェーンの非同期操作が可能であることです.ListenableFuture rowKeyFuture = indexService.lookUp(query);
AsyncFunction queryFunction =
new AsyncFunction() {
public ListenableFuture apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture queryFuture = Futures.transform(rowKeyFuture, queryFunction, queryExecutor);
他のより多くの操作はより効果的にサポートすることができ、JDKのFutureはサポートできない.
異なるアクションは異なるExecutorsで実行でき、個別のListenableFutureでは複数のアクションが待機できます.
1つの操作が開始されると、他のいくつかの操作もできるだけ早く実行されます.「fan-out」-ListenableFutureは、すべてのコールバック(callback)を促すシーンを満たすことができます.逆にもっと簡単な仕事は、同じように「fan-in」シーンを満たすことができ、ListenableFutureが計算結果を取得(get)することを促すと同時に、他のFuturesもできるだけ早く実行することができる:the implementation of Futuresを参照することができる.allAsList .(注:fan-inとfan-outはソフトウェア設計の用語で、ここを参照してください.http://baike.baidu.com/view/388892.htm#1あるいは、ここでの解析Design Principles:Fan-In vs Fan-Outを参照してください.ここでfan-outの実装は、パッケージされたListenableFutureがコールバックを通じて他のコードフラグメントを呼び出すことです.fan-inの意味は他のFutureを呼び出すことができることです)
方法
説明
リファレンス
transform(ListenableFuture , AsyncFunction , Executor) *
受信AsyncFunctionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , AsyncFunction )
transform(ListenableFuture , Function , Executor)
受信Functionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , Function )
allAsList(Iterable>)
リストenableFutureを返します.リストenableFutureが返すresultはリストです.リストの値は、各リストenableFutureの戻り値です.入力されたfailsまたはcancelのいずれかであれば、このFuture failsまたはcanceledです.
allAsList(ListenableFuture...)
successfulAsList(Iterable>)
ListenableFutureを返します.このFutureの結果には、すべての成功したFutureが含まれています.元の順序で、そのうちの1つのFailedまたはcancelがnullで置き換えられます.
successfulAsList(ListenableFuture...)
AsyncFunctionでは、非同期変換値に使用できるListenableFuture apply(A input)メソッドが提供されています.List queries;
// The queries go to all different data centers, but we want to wait until they're all done or failed.
ListenableFuture successfulQueries = Futures.successfulAsList(queries);
Futures.addCallback(successfulQueries, callbackOnSuccessfulQueries);
CheckedFuture
GuavaはCheckedFutureインタフェースも提供しています.CheckedFutureはListenableFutureであり、その中には複数のバージョンのgetメソッドが含まれており、方法は放出検査異常を宣言する.これにより、実行ロジックで異常を投げ出すことができるFutureの作成が容易になります.ListenableFutureをCheckedFutureに変換し、Futuresを使用できます.makeChecked(ListenableFuture, Function).
多くのユーザーはFuturesを使うのが好きだ.addCallback(ListenableFuture,FutureCallback,Executor)の方式、または別のバージョンversion(訳者注:addCallback(ListenableFuture future,FutureCallback super V>callback))は、デフォルトではMoreExecutorsが採用する.sameThreadExecutor()スレッドプールは、使いやすくするためにCallbackは軽量級の設計を採用している.FutureCallbackでは、次の2つの方法が実装されています.
onSuccess(V)は、Futureが成功したときに実行し、Futureの結果から判断します.
onFailure(Throwable)は、Futureが失敗したときに実行し、Futureの結果から判断します.
ListenableFutureの作成
JDKのExecutorServicesに対応する.submit(Callable)がマルチスレッド非同期演算をコミットする方式で、GuavaはListeningExecutorServiceインタフェースを提供し、このインタフェースはListenableFutureを返し、対応するExecutorServiceは通常のFutureを返す.ExecutorServiceからListeningExecutorServiceに移行するにはMoreExecutorsを使用します.ListeningDecorator(ExecutorService)が装飾しています.ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture explosion = service.submit(new Callable() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
また、FutureTaskから変換された場合、GuavaはListenableFutureTaskを提供します.CallableとListenableFutureTask.create(Runnable, V). JDKとは異なりListenableFutureTaskは勝手に継承できない(ListenableFutureTaskのdoneメソッドはlistenerを呼び出す操作を実現している).
インタフェースのメソッドではなく、抽象的な方法でfutureの値を設定するのが好きな場合は、抽象クラスAbstractFutureを継承するか、SettableFutureを直接使用することを考慮します.
他のAPIが提供するFutureをListenableFutureに変換する必要がある場合は、ハードコーディングしかできない方法はありません.ListenInPoolThread(Future)は、FutureをListenableFutureに変換します.可能な限りオリジナルのコードを修正してListenableFutureに戻るほうがいいです.
Application
ListenableFutureを使用する最も重要な理由は、一連の複雑なチェーンの非同期操作が可能であることです.ListenableFuture rowKeyFuture = indexService.lookUp(query);
AsyncFunction queryFunction =
new AsyncFunction() {
public ListenableFuture apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture queryFuture = Futures.transform(rowKeyFuture, queryFunction, queryExecutor);
他のより多くの操作はより効果的にサポートすることができ、JDKのFutureはサポートできない.
異なるアクションは異なるExecutorsで実行でき、個別のListenableFutureでは複数のアクションが待機できます.
1つの操作が開始されると、他のいくつかの操作もできるだけ早く実行されます.「fan-out」-ListenableFutureは、すべてのコールバック(callback)を促すシーンを満たすことができます.逆にもっと簡単な仕事は、同じように「fan-in」シーンを満たすことができ、ListenableFutureが計算結果を取得(get)することを促すと同時に、他のFuturesもできるだけ早く実行することができる:the implementation of Futuresを参照することができる.allAsList .(注:fan-inとfan-outはソフトウェア設計の用語で、ここを参照してください.http://baike.baidu.com/view/388892.htm#1あるいは、ここでの解析Design Principles:Fan-In vs Fan-Outを参照してください.ここでfan-outの実装は、パッケージされたListenableFutureがコールバックを通じて他のコードフラグメントを呼び出すことです.fan-inの意味は他のFutureを呼び出すことができることです)
方法
説明
リファレンス
transform(ListenableFuture , AsyncFunction , Executor) *
受信AsyncFunctionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , AsyncFunction )
transform(ListenableFuture , Function , Executor)
受信Functionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , Function )
allAsList(Iterable>)
リストenableFutureを返します.リストenableFutureが返すresultはリストです.リストの値は、各リストenableFutureの戻り値です.入力されたfailsまたはcancelのいずれかであれば、このFuture failsまたはcanceledです.
allAsList(ListenableFuture...)
successfulAsList(Iterable>)
ListenableFutureを返します.このFutureの結果には、すべての成功したFutureが含まれています.元の順序で、そのうちの1つのFailedまたはcancelがnullで置き換えられます.
successfulAsList(ListenableFuture...)
AsyncFunctionでは、非同期変換値に使用できるListenableFuture apply(A input)メソッドが提供されています.List queries;
// The queries go to all different data centers, but we want to wait until they're all done or failed.
ListenableFuture successfulQueries = Futures.successfulAsList(queries);
Futures.addCallback(successfulQueries, callbackOnSuccessfulQueries);
CheckedFuture
GuavaはCheckedFutureインタフェースも提供しています.CheckedFutureはListenableFutureであり、その中には複数のバージョンのgetメソッドが含まれており、方法は放出検査異常を宣言する.これにより、実行ロジックで異常を投げ出すことができるFutureの作成が容易になります.ListenableFutureをCheckedFutureに変換し、Futuresを使用できます.makeChecked(ListenableFuture, Function).
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture explosion = service.submit(new Callable() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
ListenableFutureを使用する最も重要な理由は、一連の複雑なチェーンの非同期操作が可能であることです.
ListenableFuture rowKeyFuture = indexService.lookUp(query);
AsyncFunction queryFunction =
new AsyncFunction() {
public ListenableFuture apply(RowKey rowKey) {
return dataService.read(rowKey);
}
};
ListenableFuture queryFuture = Futures.transform(rowKeyFuture, queryFunction, queryExecutor);
他のより多くの操作はより効果的にサポートすることができ、JDKのFutureはサポートできない.
異なるアクションは異なるExecutorsで実行でき、個別のListenableFutureでは複数のアクションが待機できます.
1つの操作が開始されると、他のいくつかの操作もできるだけ早く実行されます.「fan-out」-ListenableFutureは、すべてのコールバック(callback)を促すシーンを満たすことができます.逆にもっと簡単な仕事は、同じように「fan-in」シーンを満たすことができ、ListenableFutureが計算結果を取得(get)することを促すと同時に、他のFuturesもできるだけ早く実行することができる:the implementation of Futuresを参照することができる.allAsList .(注:fan-inとfan-outはソフトウェア設計の用語で、ここを参照してください.http://baike.baidu.com/view/388892.htm#1あるいは、ここでの解析Design Principles:Fan-In vs Fan-Outを参照してください.ここでfan-outの実装は、パッケージされたListenableFutureがコールバックを通じて他のコードフラグメントを呼び出すことです.fan-inの意味は他のFutureを呼び出すことができることです)
方法
説明
リファレンス
transform(ListenableFuture , AsyncFunction , Executor) *
受信AsyncFunctionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , AsyncFunction )
transform(ListenableFuture , Function , Executor)
受信Functionパラメータによって受信ListenableFutureに割り当てられる新しいListenableFutureを返す.
transform(ListenableFuture , Function )
allAsList(Iterable>)
リストenableFutureを返します.リストenableFutureが返すresultはリストです.リストの値は、各リストenableFutureの戻り値です.入力されたfailsまたはcancelのいずれかであれば、このFuture failsまたはcanceledです.
allAsList(ListenableFuture...)
successfulAsList(Iterable>)
ListenableFutureを返します.このFutureの結果には、すべての成功したFutureが含まれています.元の順序で、そのうちの1つのFailedまたはcancelがnullで置き換えられます.
successfulAsList(ListenableFuture...)
AsyncFunctionでは、非同期変換値に使用できるListenableFuture apply(A input)メソッドが提供されています.
List queries;
// The queries go to all different data centers, but we want to wait until they're all done or failed.
ListenableFuture successfulQueries = Futures.successfulAsList(queries);
Futures.addCallback(successfulQueries, callbackOnSuccessfulQueries);