我有一个固定线程池为15的Java应用程序,该机器Solaris 10 SPARC有16个CPU。添加池大大提高了性能,但我想知道池中是否有太多线程。使用较少的线程可以提高性能,还是Solaris可以很好地完成线程调度。
假设池大量使用十五个CPU,那么其他应用程序线程因各种原因需要CPU,并发垃圾收集就是一个很好的例子。现在,池和其他应用程序线程共享五个CPU。然后,一到七个CPU变为空闲,Solaris会将繁忙CPU上的线程共享时间移动到空闲CPU吗?
如果没有,那么保持池大小更小是否更好,以便其他应用程序线程总是有空闲的CPU?使问题更加复杂的是,应用程序中的CPU使用率非常零散。
答案 0 :(得分:4)
如果您只执行cpu密集型任务(无IO)N + 1个线程(其中N是内核数量)将为您提供最佳的处理器利用率。
+1因为您可能有页面错误,因此可以在同步期间暂停任何原因或等待时间较小的.rad。
对于执行IO的线程,这不是很容易,你必须测试最佳尺寸 书Java concurrency in practice建议将此算法作为起点:
N = number of CPUs
U = target CPU utilization (0 <= U <= 1)
W/C = ration of wait time to cpu time (measured through profiling)
threads = N * U * (1 + W/C)
IBM在其文章Java theory and practice: Thread pools and work queues中使用相同的算法,固定的U = 1。 在IBM文章中也可以阅读N + 1事实,以提供这两个论文的起源。
答案 1 :(得分:1)
拥有比CPU更多的线程通常很好,这实际上可以帮助整体吞吐量。
原因是IO可能会阻塞多个线程或在任何给定时间休眠。因此,准备执行更多线程永远不会伤害。
答案 2 :(得分:-3)
通常,如果您可以在线程和CPU之间建立1对1映射,那么您将获得最佳性能。这假设用户线程与内核线程1对1映射。如果我没记错,Solaris允许多个内核线程以及用户线程,所以在这方面你应该没问题。当多个线程使用相同的CPU时,您将遇到瓶颈。
与往常一样,关于减少线程池大小的问题的最佳建议是:“尝试并对其进行基准测试。” (但我怀疑在这种情况下会更好。)
至于您关于正在运行的其他应用程序的问题,Solaris将使用CPU在您的线程池和其他应用程序之间进行切换。如果CPU变为空闲,Solaris会将一些线程移动到空闲CPU。
编辑:Here是Sun关于Solaris和Java线程模型如何交互的链接。