Java中的线程池执行器

时间:2016-06-15 19:03:49

标签: java multithreading executorservice threadpoolexecutor

ExecutorService threadPool = Executors.newFixedThreadPool(N);

for (Runnable task : tasks) {
    threadPool.execute(task);
}

我对多线程有点新意。这是我在最近的一次采访中得到的一个问题。有人可以帮助我解决方案和明确的解释。 在上面的代码中,每个任务花费25%的时间进行计算,75%的时间进行I / O.假设一个四核机器(没有超线程),线程池N的大小应该是什么,以实现最佳性能而不浪费线程假设无限的I / O容量。

2 个答案:

答案 0 :(得分:1)

如果您的机器具有无限的I / O,则意味着您可以完全专注于CPU。每个任务在运行时使用四分之一的CPU。这意味着,您可以运行四个任务来使一个CPU内核饱和,并使四核机器上的N = 16。

然而,这纯粹是理论上的答案。实际上,您会发现为什么N = 16可能太大或太小的几个问题。例如,假设所有16个任务的调度(CPU与IO)相同,并且在同一时刻启动。这意味着,在第一个CPU中,强时间帧执行速度降低到四分之一(16个线程争用四个CPU)。此外,可以假设,运行OS,调度程序,垃圾收集等需要一定量的CPU负载。这会使N = 16太大。

另一方面,如果不要求每个任务以最大单独速度运行,则较大的N可能会给您更好的整体性能,例如,如果在某个时间范围内超过3/4线程正在进行I / O,这会在当时留下未使用的CPU资源。

我认为,这不是面试问题的重点,但在现实世界中需要考虑的事项。

答案 1 :(得分:1)

如果IO不是约束(由于无限的IO容量),您可以专注于可用的核心数量。

ExecutorService threadPool = Executors.newFixedThreadPool(
                             Runtime.getRuntime().availableProcessors());

如果在Executors中使用newWorkStealingPool(来自java 8发行版),性能将得到进一步提升

public static ExecutorService newWorkStealingPool()
  

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