Java 设置线程池的理想大小

Java 设置线程池的理想大小,java,multithreading,concurrency,cpu-cores,processors,Java,Multithreading,Concurrency,Cpu Cores,Processors,两者的区别是什么- newSingleThreadExecutor与newFixedThreadPool(20) 从操作系统和编程的角度来看 每当我使用newSingleThreadExecutor运行我的程序时,我的程序运行得非常好,端到端延迟(第95百分位)大约为5ms 但是一旦我开始使用- newFixedThreadPool(20) 我的程序性能下降,我开始看到端到端延迟为37ms 所以现在我试图从架构的角度来理解线程的数量在这里意味着什么?如何确定我应该选择的最佳线程数 如果我使用更多

两者的区别是什么-

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定律解释得很好。从维基

阿姆达尔定律指出,如果p是一个程序中可以并行化的部分(即,并行化的好处),和(1− P) 是无法并行化(保持串行)的比例,则使用N个处理器可实现的最大加速比为

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

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

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

所以现在我试图从架构的角度来理解线程的数量在这里意味着什么

每个线程都有自己的堆栈内存、程序计数器(就像指向下一步执行的指令的指针)和其他本地资源。交换它们会影响单个任务的延迟。好处是当一个线程空闲时(通常在等待i/o时),另一个线程可以完成工作。另外,如果有多个处理器可用,那么如果任务之间没有资源和/或锁定争用,它们可以并行运行

如何确定我应该选择的最佳线程数

交换价格与避免空闲时间的机会之间的权衡取决于任务外观的小细节(有多少i/o、何时、i/o之间有多少工作、使用多少内存来完成)。实验始终是关键

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


吞吐量通常会先呈线性增长,然后是相对平坦的部分,然后是下降(可能非常陡峭)。每个系统都是不同的。

看看阿姆达尔定律就可以了,特别是如果你确切知道p和N有多大的话。因为这种情况永远不会发生,所以您可以监视性能(无论如何都应该这样做),增加/减少线程池大小,以优化对您来说很重要的性能指标。

您对这里的答案不满意吗:?我想了解更多细节。我发布的那个问题更多的是关于编程和发现瓶颈,但格雷暗示这可能是线程大小的问题。所以我想让我们发布另一个问题,但这次更具体到架构的角度。谢谢Jatin的建议。关于内核大小,我还发布了我的机器在linux中的配置规范,你能知道我的内核大小是多少吗?由于我无法通过查看配置规范来确定这一点。@TechGeeky调用
Runtime.getRuntime().AvailableProcessor()
将返回coresYeah的数量,看起来我的load and performance机器中只有2个内核。我用20个线程运行我的程序,这就是我在程序中看到这么多高性能问题的原因。对吧?@TechGeeky绝对是
20实际上是一个kill:P。我建议,根据Amadhal定律设置大小,并通过增加或减少该值周围的池大小来处理它。是的,我们肯定会处理这个问题。还有一件事我想澄清的是当你说游泳池大小时。在这个代码
newFixedThreadPool(threads)
中,您谈论的是
threads
。对吗?我应该在那里使用
3
,但我可以再次使用这些数字,看看它是如何运行的