Java 为什么ExecutorService方法invokeAny()在每次程序运行时处理不同数量的任务?

Java 为什么ExecutorService方法invokeAny()在每次程序运行时处理不同数量的任务?,java,multithreading,executorservice,java.util.concurrent,Java,Multithreading,Executorservice,Java.util.concurrent,请看以下代码: 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.MILLISECOND

请看以下代码:

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
有人能解释一下为什么会这样吗

在Oracle的文档中,关于方法
invokeAny(集合)只有一个短语
它是否会在一个任务完成后取消剩余的任务

是的,没错,但这并不意味着只有在当前任务完成后,它才会提交/启动下一个任务,这是整个并发点,它不会等待上一个任务完成。逐个提交任务,不要等待任务完成,同时检查是否有任务完成,如果完成,取消所有当前任务在不运行任务时,不提交剩余任务,只返回已完成的任务


现在,在最终取消正在运行的任务之前,它们可能已经完成了工作,也可能没有,在您的例子中,print语句取决于每个线程获得的时间片,这取决于注释中指出的各种JVM和系统因素。

您创建了一个
Executors.newFixedThreadPool()
使用
2
线程。因此,我假设两个任务被提交,有时它们可能同时完成(或不完成),结果就是这样。并发性取决于不同的因素。例如JVM正在做什么,以及您的计算机在后台做什么。这样,一个任务可能比另一个任务完成得更快或更慢
Callable task's execution