0

当我ExecutorService 在 JAVA 中使用以下代码创建时,有人可以解释它是如何ExecutorService工作的吗?

ExecutorService executor = Executors.newFixedThreadPool(400);

    for (int i = 0; i < 500; i++) {
        Runnable worker = new MyRunnable(10000000L + i);
        executor.execute(worker);
    }

我相信会有一个工作队列,我的 for 循环会Runnable向这个队列添加 500 个任务。现在ExecutorService已经创建了一个包含 400 个线程的线程池。

那么在队列中的这 500 个任务中,队列中的 400 个线程ExecutorService将一次执行这 400 个任务,而剩余的 as slot 被释放?

我的理解正确吗?

4

2 回答 2

2

JavaDoc newFixedThreadPool

创建一个线程池,该线程池重用在共享无界队列上运行的固定数量的线程。在任何时候,最多 nThreads 个线程将是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,它们将在队列中等待,直到有线程可用。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,新的线程将取代它。池中的线程将一直存在,直到显式关闭。

于 2012-10-13T23:57:26.183 回答
0

如果任务多于处理线程数,则尚未被线程拾取的任务将等待。一旦线程完成一项任务,它就会再接一个等待的任务。

但是这些线程池(除了ForkJoinPool)在窃取工作线程任务方面效率不高。

假设一个线程积压了 10 个要执行的任务并且它正在运行第一个任务。同时,池中的其他一些线程处于空闲状态。在这种情况下,一旦为任务分配了一个线程,即使其他线程处于空闲状态,也只有该线程将执行该任务。

ForkJoinPool与其他类型的 ExecutorService 的不同之处主要在于采用了工作窃取:池中的所有线程都尝试查找并执行提交到池和/或由其他活动任务创建的任务(如果不存在,则最终阻塞等待工作)

Java 8 中又添加了一个新的 API。

public static ExecutorService newWorkStealingPool()

创建一个工作窃取线程池,使用所有可用处理器作为其目标并行度级别。

相关 SE 问题:ThreadPoolExecutor vs ForkJoinPool:窃取子任务

于 2016-01-14T07:40:29.297 回答