如何解决为什么ExecutorService方法invokeAny在每次运行的程序上都处理不同数量的任务?
看下面的代码:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class InvokeAny {
public static void main(String[] args) {
Callable<String> callableTask = () -> {
TimeUnit.MILLISECONDS.sleep(300);
System.out.println("Callable task's execution");
return "Task's execution";
};
List<Callable<String>> callableTasks = new ArrayList<>();
callableTasks.add(callableTask);
callableTasks.add(callableTask);
callableTasks.add(callableTask);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
executorService.invokeAny(callableTasks);
} catch (InterruptedException | ExecutionException e) {
e.printstacktrace();
}
shutdownAndAwaitTermination(executorService);
}
private static void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(1000,TimeUnit.MILLISECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(1000,TimeUnit.MILLISECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}
每次运行程序时,在控制台中都会得到不同的结果。
第一次运行:
Callable task's execution
第二次运行:
Callable task's execution
Callable task's execution
第三次运行:
Callable task's execution
有人可以解释一下为什么会这样吗?
在Oracle文档中,关于方法invokeAny(Collection<? extends Callable<T>> tasks)
只有一句话:
执行给定的任务,返回具有以下条件的任务的结果 成功完成(即没有引发异常)(如果有)
我想了解它的工作原理。完成一项任务后,它会取消剩余的任务吗?如果可以,为什么有时我会执行2个任务?
解决方法
完成一项任务后,它会取消剩余的任务吗?
是的,这是正确的,但这并不意味着它将仅在当前任务完成后才提交/启动下一个任务,这就是并发的全部目的,它不等待上一个任务完成。一次提交任务,不要等待任务完成,同时检查是否有任务完成,是否完成,取消所有当前正在运行的任务,不提交其余任务而只返回完成的任务。>
现在,在最终取消正在运行的任务之前,它们可能已经完成了工作,或者可能没有完成(对于您而言是print语句),具体取决于每个线程获得的时间片,这取决于各种JVM和系统因素,例如在评论中指出。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。