gpt4 book ai didi

java - ListenableFuture、FutureCallback 和超时

转载 作者:IT老高 更新时间:2023-10-28 20:58:58 28 4
gpt4 key购买 nike

根据我看到的 Guava 示例,我一直在寻找优雅的解决方案来解决我的问题。具体来说,我喜欢 Futures.addCallback(ListenableFuture, FutureCallback) 的方式有效,但我希望能够在调用 FutureCallback 之前可以过期的时间长度上设置超时。理想情况下,如果违反超时只是导致 FutureCallback 的失败条件被调用,那就太好了。

Guava 已经有这样的东西了吗?只是不建议尝试将超时与回调结合起来吗?

编辑:包括导致我这一点的代码示例。显然,我去掉了有意义的部分来获得一个最小的例子。

@Test
public void testFuture()
{
Callable<Boolean> callable = new Callable<Boolean>()
{

@Override
public Boolean call() throws Exception
{
while(true);
}
};

ListenableFuture<Boolean> callableFuture = MoreExecutors.listeningDecorator(Executors.newSingleThreadExecutor()).submit(callable);

Futures.addCallback(callableFuture, new FutureCallback<Boolean>()
{

@Override
public void onFailure(Throwable arg0)
{
System.out.println("onFailure:"+arg0);
}

@Override
public void onSuccess(Boolean arg0)
{
System.out.println("onSuccess:"+arg0);
}
});

try
{
callableFuture.get(1000, TimeUnit.MILLISECONDS);
}catch(Throwable t)
{
System.out.println("catch:"+t);
}
}

此代码只会打印 catch:java.util.concurrent.TimeoutException

最佳答案

更新:这已作为 Futures.withTimeout() 添加到 Guava .


在内部,我们有一个 makeTimeoutFuture 方法,它接受一个 Future 作为输入并返回一个新的 Future 将具有相同的结果 除非原件没有在给定的截止日期前完成。如果截止日期到期,则输出 Future 将其结果设置为 TimeoutException。因此,您可以调用 makeTimeoutFuture 并将监听器附加到输出 Future

makeTimeoutFuture 不是解决问题的最自然方法。事实上,我认为创建该方法主要是为了在无参数 get() 调用上设置硬超时,因为将所需的截止日期传播给所有调用者可能会很痛苦。一个更自然的解决方案是推理 get()get(long, TimeUnit) 因为 addCallback(ListenableFuture, FutureCallback)addCallback(ListenableFuture, FutureCallback, long, TimeUnit, SchededuledExecutorService).这有点笨拙,尽管不如 makeTimeoutFuture。在做任何事情之前,我想多考虑一下。你愿意file a feature request ?

(这是我们内部的:)

public static <V> ListenableFuture<V> makeTimeoutFuture(
ListenableFuture<V> delegate,
Duration duration,
ScheduledExecutorService scheduledExecutor)

如果指定的持续时间到期,则返回一个委托(delegate)给另一个但将提前完成的 future (通过包装在 ExecutionException 中的 TimeoutException)。在这种情况下,委托(delegate) future 不会被取消。

scheduledExecutor.schedule(new Runnable() {
@Override public void run() {
TimeoutFuture.this.setException(new TimeoutException("Future timed out"));
}
}, duration.getMillis(), TimeUnit.MILLISECONDS);

关于java - ListenableFuture、FutureCallback 和超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12380726/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com