2016-04-12 19 views
2

私は自分の仕事を持っているし、そのためのフォールバック:FallbackFutureを使用してTimeoutExceptionを処理する方法

ListenableFuture<T> listenableAsyncTask = executorService.submit(asyncTaskCallable); 
ListenableFuture<T> listenableFallbackTask = executorService.submit(fallBackTaskCallable); 

彼らから、私は失敗寛容ListenableFuture形成:

ListenableFuture<T> failTolerantListenableFuture = Futures.withFallback(listenableAsyncTask, new FutureFallback<T>() { 
       @Override 
       public ListenableFuture<T> create(Throwable t) throws Exception { 
        return listenableFallbackTask; 
       } 
      }); 

をそして私は失敗寛容先物のリストを持っている:

List<ListenableFuture<T>> listenableFutures = ...; 

一定の時間内に結果を得るタイミングです:

result = Futures.allAsList(listenableFutures).get(50,TimeUnit.MILLISECONDS); 

この時点で、タスクが50ms以内に終了しなかった場合、リターン出力はfallbackTaskによって処理されることが予想されます。これは軽量です。

java.util.concurrent.TimeoutException: Timeout waiting for task. 

私は他の成功したタスクからすべての結果を失う原因:私は予定通り

しかし、私は次の例外を持っていません。この場合、フォールバックは私にとってはうまくいきませんでした。それとも私はその概念を誤解しましたか?

答えて

6

Futureが失敗しました」と「Future.getが失敗しました」とを区別する必要があります。

  • 送信したタスクが例外をスローすると、「Futureは失敗します。 (。withFallbackの目的のために、我々はまた、それはしかし、ここでは関係ありません失敗をするのキャンセルを考え、そして行動はいつか変わることがあります。)
  • 場合は、次のいずれかのが起こる「Future.getの呼び出しが失敗した」:
    • Futureは、コールが
を中断さ
  • アウト
  • コール回失敗します

    withFallbackは、タイムアウトまたは中断のケースを処理することなく、Futureが失敗した場合のみを処理します。

    50ミリ秒以内に実行されたすべての主要結果を取得し、その他のすべてのケースをセカンダリ結果に戻す場合は、withTimeoutを使用して与えられた後自動的にFutureに失敗しますタイムアウト:

    List<ListenableFuture<T>> originalFutures = ...; 
    List<ListenableFuture<T>> defaultAfterTimeoutFutures = new ArrayList<>(); 
    for (ListenableFuture<T> f : originalFutures) { 
        f = Futures.withTimeout(f, 50, MILLISECONDS, executor); 
        f = Futures.withFallback(f, ...); 
        defaultAfterTimeoutFutures.add(f); 
    } 
    result = Futures.allAsList(defaultAfterTimeoutFutures).get(); 
    

    しかし、その最後のget呼び出しが長い50ミリ秒以上待つことに注意:主Futureが失敗した場合は、そのフォールバックが行われるまで、get呼び出しは待たなければなりません。フォールバックを待っていない場合は、withTimeoutでラップする必要があります。そして、あなたがそれらをラップすると、タイムアウト後に失敗します。その時点では、allAsListも失敗します。それが欲しくない場合は、successfulAsListallAsListの代わりに)を使用するか、今度は常にwithFallbackでラッパーをラップする必要があります。

  • +0

    WithFallbackラッピングに関する明確な説明をいただきありがとうございます:) – Xitrum

    関連する問題