gpt4 book ai didi

java - 如何使用 ExecutorService 和 Futures 处理 TimeoutException?

转载 作者:行者123 更新时间:2023-12-01 06:19:54 25 4
gpt4 key购买 nike

我有以下示例代码,假设 MyCallable("B") 的执行时间超过一秒,而其他代码的执行速度超过一秒。因此,在调用 Future.get() 的循环中,它将抛出 TimeoutException

public static void main(String[] args) {
ExecutorService es = Executors.newFixedThreadPool(2);

List<Future<String>> futures = new ArrayList<Future<String>>();

futures.add(es.submit(new MyCallable("A")));
futures.add(es.submit(new MyCallable("B")));
futures.add(es.submit(new MyCallable("C")));
futures.add(es.submit(new MyCallable("D")));
futures.add(es.submit(new MyCallable("E")));

try {
for(Future<String> f : futures) {
try {
System.out.println("result " + f.get(1, TimeUnit.SECONDS));
}
catch (TimeoutException e) {
// how do I know which MyCallable() has timed out?
} catch (ExecutionException e) {
System.out.println(e.getMessage());
}
}
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally {
es.shutdown();
}
}

正如预期的那样,每个 MyCallable() 实例都会执行,但对于超时的实例,我想执行一些错误处理,这需要知道哪个 Callable 与哪个 Future 关联

是否有这种关联的机制,或者由我的 Callable 来处理其 call() 方法内的所有错误处理?

最佳答案

看起来你可以简单地维护 Map<Future<String>, Callable<String>>而不是List<Future<String>>并以这种方式检索原始的 Callable。

如果你想变得更聪明,你可以采用 OO 风格并扩展 ThreadPoolExecutor 并创建一个 Future 装饰器类。我认为这可能有点矫枉过正,但你可以这样做:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


public class FutureWithCallable<T> implements Future<T> {
private final Callable<T> callable;
private final Future<T> wrapped;

public FutureWithCallable(Future<T> wrapped, Callable<T> callable) {
this.callable = callable;
this.wrapped = wrapped;
}

public Callable<T> getCallable() {
return callable;
}

@Override
public boolean cancel(boolean mayInterruptIfRunning) {
return wrapped.cancel(mayInterruptIfRunning);
}

@Override
public T get() throws InterruptedException, ExecutionException {
return wrapped.get();
}

@Override
public T get(long timeout, TimeUnit unit) throws InterruptedException,
ExecutionException, TimeoutException {
return wrapped.get(timeout, unit);
}

@Override
public boolean isCancelled() {
return wrapped.isCancelled();
}

@Override
public boolean isDone() {
return wrapped.isDone();
}
}

然后:

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ExecutorServiceWithCallable extends ThreadPoolExecutor {

public ExecutorServiceWithCallable(int corePoolSize, int maxPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
super(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue);
}

@Override
public <T> FutureWithCallable submit(Callable<T> callable) {
Future<T> future = super.submit(callable);
return new FutureWithCallable<T>(future, callable);
}

}

关于java - 如何使用 ExecutorService 和 Futures 处理 TimeoutException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12150213/

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