繁体   English   中英

Java中的线程池执行器

[英]Thread Pool Executor in Java

ExecutorService threadPool = Executors.newFixedThreadPool(N);

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

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

如果您的机器具有无限的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资源。

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

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

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

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

public static ExecutorService newWorkStealingPool()

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM