java – 处理器核心数与线程池的大小

前端之家收集整理的这篇文章主要介绍了java – 处理器核心数与线程池的大小前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
很多时候,我听说在线程池中维护线程数目比该系统内核数更好.具有比核心数多两倍或更多的线程不仅是浪费,而且还可能导致性能下降.

是真的吗如果没有,剥夺这些声明的根本原则是什么(具体涉及到java)?

解决方法

声明是不正确的一般声明.也就是说,有时它们是真实的(或者真实的),而其他时候他们是虚伪的.

几件事情是无可争辩的真实:

>更多线程意味着更多的内存使用.每个线程需要一个线程栈.对于最近的HotSpot JVM,最小线程堆栈大小为64Kb,默认值可以高达1Mb.这可能是重要的.此外,任何活着的线程都可能拥有或共享堆中的对象,无论它当前是否可运行.因此,合理的是期望更多的线程意味着更大的存储器工作集.
>执行硬件上的核心(或超线程内核或其他任何内核),JVM不能实际运行更多的线程.一辆汽车不会在没有发动机的情况下运行,并且一个线程不会运行没有一个核心.

除此之外,事情变得不那么明确. “问题”是一个活动的线程可以在各种“状态”.例如:

活动线程可以运行;即主动执行指令.
活动线程可以运行;即等待一个核心,以便它可以运行.
活动线程可以通过同步;即等待来自另一线程的信号,或等待释放锁.
活动线程可以等待外部事件;例如等待一些外部服务器/服务来响应请求.

“每个核心一个线程”启发式假设线程正在运行或可运行(根据上述).但是对于很多多线程应用程序,启发式是错误的…因为它不考虑其他状态的线程.

现在“太多”线程明显可以导致显着的性能下降,通过使用太多内存简单. (想象一下,您拥有4Gb的物理内存,并创建8,000个线程,具有1Mb堆栈,这是虚拟内存颠覆的一个方法.)

但是其他的东西呢线程太多会导致上下文切换过多?

我不这么认为如果您有很多线程,并且您的应用程序使用这些线程可能会导致过多的上下文切换,并且这对于性能不利.然而,我认为上下文切换的根本原因不是实际的线程数.性能问题的根源更可能是应用程序:

>以特别浪费的方式同步;例如当Object.notify()会更好的时候使用Object.notifyAll()
>在高度竞争的数据结构上同步OR
>相对于每个线程正在做的有用的工作量,做太多的同步
>试图做太多的I / O并行.

(在最后一种情况下,瓶颈可能是I / O系统,而不是上下文切换…除非I / O是同一机器上具有服务/程序的IPC).

另一方面,在上述不存在混淆因素的情况下,多线程不会增加上下文切换.如果您的应用程序有N个可运行的线程竞争M个处理器,并且线程纯粹是计算和无竞争的,那么操作系统的线程调度程序将尝试在它们之间进行时间分片.但是,时间片长度可能会在十分之一秒(或更多)内测量,因此与cpu绑定线程在其切片中实际执行的工作相比,上下文切换开销可以忽略不计.如果我们假设时间片的长度是恒定的,那么上下文切换开销也将是恒定的.添加更多可运行的线程(增加N)不会显着地改变工作与开销的比率.

总而言之,“太多线程”对于性能是有害的.然而,实际上有多少“太多”,没有一个普遍的“经验法则”. (幸运的是),在性能问题变得显着之前,您通常有相当大的余地.

猜你在找的Java相关文章