当我用下面的代码创建ExecutorService时,有人能解释一下ExecutorService是如何工作的吗?
ExecutorService executor = Executors.newFixedThreadPool(400);
for (int i = 0; i < 500; i++) {
Runnable worker = new MyRunnable(10000000L + i);
executor.execute(worker);
}我相信将会有一个工作队列,我的for循环将向这个队列中添加500个Runnable任务。现在,已经创建了具有400个线程的线程池的ExecutorService。
那么,在队列中的500个任务中,ExecutorService中的400个线程将一次执行这400个任务,其余的as插槽将被释放吗?
我的理解是正确的吗?
发布于 2012-10-14 07:57:26
JavaDoc newFixedThreadPool
创建了一个线程池,该线程池重用了固定数量的线程,这些线程在共享的无界队列中运行。在任何时候,至多nThreads线程都将是活动的处理任务。如果在所有线程都处于活动状态时提交额外的任务,则这些任务将在队列中等待,直到有线程可用为止。如果任何线程在关闭之前的执行过程中由于失败而终止,如果需要执行后续任务,则会有一个新的线程来代替它。池中的线程将一直存在,直到它被显式关闭。
发布于 2016-01-14 15:40:29
如果任务数大于处理线程数,则未被线程拾取的任务将等待。一旦线程完成了一个任务,它就会再接一个等待的任务。
但是这些线程池(而不是ForkJoinPool)在窃取工作线程任务方面效率不高。
假设一个线程积压了10个要执行的任务,并且它正在运行第一个任务。同时,池中的某些其他线程处于空闲状态。在这种情况下,一旦为任务分配了线程,即使其他线程空闲,也只有该线程会执行该任务。
ForkJoinPool与其他类型的ExecutorService的主要区别在于采用了工作窃取:池中的所有线程都试图查找并执行提交到池和/或由其他活动任务创建的任务(如果不存在任务,则最终阻塞等待工作)。
Java 8中又添加了一个新的API。
public static ExecutorService newWorkStealingPool()使用所有可用的处理器作为其目标并行级别来创建工作窃取线程池。
相关SE问题:ThreadPoolExecutor vs ForkJoinPool: stealing subtasks
https://stackoverflow.com/questions/12878051
复制相似问题