gpt4 book ai didi

java - ExecutorService.awaitTermination() 永远不会超时

转载 作者:行者123 更新时间:2023-12-01 21:18:45 25 4
gpt4 key购买 nike

我正在尝试实现一个函数,其中可调用对象在规定时间内完成或操作超时。我曾希望 ExecutorService.awaitTermination() 能够执行此操作,但惊讶地发现它没有执行此操作。代码如下。运行永远不会完成。

public class Counter implements Callable<Void> {

public static void main(String[] args) throws InterruptedException {
final Map<String, Counter> map = new HashMap<>();
map.put("", new Counter());
final Map<String, Future<Void>> result = executeTasksInParallel(map);
final Future<Void> voidFuture = result.get("");
try {
voidFuture.get();
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public Void call() throws Exception {
for (long i = 0L; i < Long.MAX_VALUE; i++);
return null;
}

public static <K, V> Map<K, Future<V>> executeTasksInParallel(final Map<K, ? extends Callable<V>> callablesById) throws InterruptedException {
final Map<K, Future<V>> resultFuturesById = new HashMap<>();
final ExecutorService executorService = Executors.newFixedThreadPool(callablesById.size());
for (final Map.Entry<K, ? extends Callable<V>> callableByIdEntry : callablesById.entrySet()) {
final K id = callableByIdEntry.getKey();
final Callable<V> callable = callableByIdEntry.getValue();
final Future<V> resultFuture = executorService.submit(callable);
resultFuturesById.put(id, resultFuture);
}
executorService.shutdown();
executorService.awaitTermination(5L, TimeUnit.SECONDS);
return resultFuturesById;
}
}

我在这里遗漏了什么吗?谢谢!

更新:

我尝试用下面的内容替换 try block 内容以避免 Future.get() 阻塞,但这也没有帮助

if (voidFuture.isDone()) {
voidFuture.get();
}

最佳答案

  1. 使用shutdownNow()正如 Joe C 所指定的...
  2. ...但只有当你的代码在 call() 中时它才会起作用。允许它这样做,例如通过检查当前线程是否被中断。参见例如this question及其详细答案。有时,如果循环调用(直接或间接)通过抛出 InterruptedException 正确处理中断请求的方法,您可能会在循环中没有这种“协作”行为。 (例如 Thread.sleep(...)Object.wait(...)Future.get(...) 、实现 InterruptibleChannel 的 channel 上的阻塞操作等)。 编辑: ...如果 InterruptedException抛出的内容不会被抑制。
  3. 是的,只需调用 get()如果 future isDone() (因为它位于主线程上,不受您的 executorService 管理)。

最终的代码是

public class Counter implements Callable<Void> {

public static void main(String[] args) throws InterruptedException {
final Map<String, Counter> map = new HashMap<>();
map.put("", new Counter());
final Map<String, Future<Void>> result = executeTasksInParallel(map);
final Future<Void> voidFuture = result.get("");
try {
if (voidFuture.isDone()) {
voidFuture.get();
}
} catch (Exception e) {
e.printStackTrace();
}
}

@Override
public Void call() throws Exception {
for (long i = 0L; i < Long.MAX_VALUE; i++) {
if (Thread.currentThread().isInterrupted()) {
Thread.currentThread().interrupt(); // restore interrupted flag
return null;
}
/* or e.g. throw an exception */
}
return null;
}

public static <K, V> Map<K, Future<V>> executeTasksInParallel(
final Map<K, ? extends Callable<V>> callablesById)
throws InterruptedException {
final Map<K, Future<V>> resultFuturesById = new HashMap<>();
final ExecutorService executorService =
Executors.newFixedThreadPool(callablesById.size());
for (final Map.Entry<K, ? extends Callable<V>> callableByIdEntry : callablesById
.entrySet()) {
final K id = callableByIdEntry.getKey();
final Callable<V> callable = callableByIdEntry.getValue();
final Future<V> resultFuture = executorService.submit(callable);
resultFuturesById.put(id, resultFuture);
}
executorService.shutdown();
executorService.awaitTermination(5L, TimeUnit.SECONDS);
executorService.shutdownNow();
return resultFuturesById;
}
}

关于java - ExecutorService.awaitTermination() 永远不会超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39481849/

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