java - 设置理想的线程池大小

标签 java multithreading concurrency cpu-cores processors

有什么区别-

newSingleThreadExecutor 与 newFixedThreadPool(20)

从操作系统和编程的角度来看。

每当我使用 newSingleThreadExecutor 运行我的程序时,我的程序运行良好,端到端延迟(第 95 个百分位)大约在 5ms 左右。

但是一旦我开始运行我的程序使用-

newFixedThreadPool(20)

我的程序性能下降,我开始看到端到端延迟为 37ms

所以现在我试图从架构的角度来理解线程数在这里意味着什么?以及如何确定我应该选择的最佳线程数是多少?

如果我使用更多的线程,会发生什么?

如果有人能用通俗的语言向我解释这些简单的事情,那对我来说将非常有用。感谢您的帮助。

我的机器配置规范-我正在从 Linux 机器上运行我的程序-

processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 45
model name      : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz
stepping        : 7
cpu MHz         : 2599.999
cache size      : 20480 KB
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm arat pln pts
bogomips        : 5199.99
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

processor       : 1
vendor_id       : GenuineIntel
cpu family      : 6
model           : 45
model name      : Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz
stepping        : 7
cpu MHz         : 2599.999
cache size      : 20480 KB
fpu             : yes
fpu_exception   : yes
cpuid level     : 13
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good xtopology tsc_reliable nonstop_tsc aperfmperf pni pclmulqdq ssse3 cx16 sse4_1 sse4_2 popcnt aes hypervisor lahf_lm arat pln pts
bogomips        : 5199.99
clflush size    : 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:

最佳答案

好的。理想情况下,假设您的线程没有锁定,因此它们不会相互阻塞(彼此独立),并且您可以假设工作负载(处理)是相同的,那么事实证明,池大小为 Runtime.getRuntime().availableProcessors()availableProcessors() + 1 给出最好的结果。

但是说,如果线程相互干扰或涉及 I/O,那么 Amadhal 定律可以很好地解释。来自维基,

Amdahl's law states that if P is the proportion of a program that can be made parallel (i.e., benefit from parallelization), and (1 − P) is the proportion that cannot be parallelized (remains serial), then the maximum speedup that can be achieved by using N processors is

Amadhal law

在您的情况下,根据可用内核的数量以及它们的具体工作(纯计算?I/O?持有锁?因某些资源而阻塞?等等),您需要提出解决方案根据以上参数。

例如:几个月前,我参与了从数字网站收集数据的工作。我的机器是 4 核的,池大小为 4。但是因为操作是纯 I/O 并且我的网速​​不错,我意识到我在 7 的池大小时性能最好。那是因为,线程不是为了计算能力而战,而是为了 I/O。所以我可以利用更多线程可以积极竞争核心这一事实。

PS:我建议阅读 Brian Goetz 所著的《Java 并发实践》一书中的“性能”一章。它详细处理了这些问题。

关于java - 设置理想的线程池大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16128436/

相关文章:

C++:如何读取大文本文件并更快地保存到数组

loops - 是否可以从外部功能停止股票行情/股票报价?

java - 单击时将数据 RecyclerView 数据传递到另一个 Activity

java - 当用户在字段中输入时,将 $ 符号添加到文本字段中

java - Spring FileSystemResource 下载文件,同时保留原始文件名

c# - 从另一个线程调用 show 后 Windows 窗体窗体挂起

java - java中构造函数线程的方法引用是安全的吗?

java - ConcurrentWeakKeyHashMap size() 方法

python - gunicorn 和/或 celery : What is the way get the best out of both?

java - 带属性的 Spring 单例