Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用FallbackFuture处理TimeoutException?_Java_Guava - Fatal编程技术网

Java 如何使用FallbackFuture处理TimeoutException?

Java 如何使用FallbackFuture处理TimeoutException?,java,guava,Java,Guava,我有我的任务,我有退路: ListenableFuture<T> listenableAsyncTask = executorService.submit(asyncTaskCallable); ListenableFuture<T> listenableFallbackTask = executorService.submit(fallBackTaskCallable); 此时,我希望如果任务未能在50ms内完成,返回输出将由fallBackTask处理,这是一个轻量

我有我的任务,我有退路:

ListenableFuture<T> listenableAsyncTask = executorService.submit(asyncTaskCallable);
ListenableFuture<T> listenableFallbackTask = executorService.submit(fallBackTaskCallable);
此时,我希望如果任务未能在50ms内完成,返回输出将由fallBackTask处理,这是一个轻量级任务

但并不像我计划的那样,我得到了以下例外:

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

这导致我失去了其他成功任务的所有结果。在这种情况下,我的退路似乎不起作用。还是我误解了这个概念

我们需要区分“未来失败”和“调用
Future.get
失败”

  • 如果您提交的任务引发异常,“未来将失败”。(对于<>代码>后退< /代码>,我们也认为取消是失败的。但是,这在这里并不相关,并且行为可能在某天发生改变。)
  • 如果发生以下任何情况,“调用
    Future.get
    失败”:
    • 未来
      失败
    • 电话超时了
    • 电话中断了
withFallback
仅处理
Future
失败的情况,而不处理超时或中断的情况

如果您的目标是检索在50毫秒内完成的所有主要结果,而所有其他情况都返回到次要结果,则可以尝试类似的方法,它使用
withTimeout
在给定超时后自动使
未来
失败:

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();
列出原始未来=。。。;
List DefaultAfterTimeOutputures=new ArrayList();
对于(列出的未来f:原始未来){
f=未来。带超时(f,50,毫秒,执行器);
f=期货。有回退(f,…);
defaultAfterTimeoutFutures.添加(f);
}
结果=Futures.allAsList(defaultAfterTimeOutputures.get();

但请注意,最后一个
get
调用的等待时间可能超过50毫秒:如果主
Future
失败,则
get
调用必须等待,直到其回退完成。如果您不想等待回退,那么还需要使用
withTimeout
来包装它们。如果您确实包装了它们,那么它们将在超时后失败,此时
allAsList
也将失败。如果您不想这样做,那么您需要使用
successfulAsList
(而不是
allAsList
),或者再次使用
withFallback
包装包装,这一次使用的值总是立即可用。

非常感谢您对withFallback包装的清晰解释:)
result = Futures.allAsList(listenableFutures).get(50,TimeUnit.MILLISECONDS);
java.util.concurrent.TimeoutException: Timeout waiting for task.
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();