当我在JAVA中使用以下代码创建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
个任务。现在ExecutorService
已经创建了一个包含400个线程的线程池。
在队列中的那500个任务中,ExecutorService
中的400个线程将一次执行400个任务,剩余的作为插槽被释放?
我的理解是否正确?
答案 0 :(得分:2)
创建一个重用固定数量的线程的线程池 关闭共享的无界队列。在任何时候,最多nThreads线程 将是主动处理任务。 如果提交了其他任务 当所有线程都处于活动状态时,它们将在队列中等待直到a 线程可用。如果任何线程因期间失败而终止 在关机之前执行,如果需要,新的将取代它 执行后续任务。池中的线程将一直存在 它是明确关闭的。
答案 1 :(得分:0)
如果任务超过处理线程数,则线程未获取的任务将等待。一旦线程完成一项任务,它将再次启动一项等待任务。
但是这些线程池(ForkJoinPool
除外)在窃取工作线程任务方面效率不高。
假设一个线程是要执行的10个任务的积压,并且它正在运行第一个任务。同时,池中的其他一些线程处于空闲状态。在这种情况下,一旦为任务分配了一个线程,即使其他线程处于空闲状态,该线程也只会执行该任务。
ForkJoinPool与其他类型的ExecutorService的不同之处主要在于使用工作窃取:池中的所有线程都尝试查找和执行提交到池的任务和/或由其他活动任务创建的任务(最终阻塞等待工作,如果不存在)
Java 8中又添加了一个新的API。
public static ExecutorService newWorkStealingPool()
使用所有可用处理器作为目标并行级别创建工作窃取线程池。
相关SE问题:ThreadPoolExecutor vs ForkJoinPool: stealing subtasks