2014-05-03 69 views
0

我在java弹簧中有一个应用程序。该应用程序需要多线程。所以我使用可调用的&执行器服务,因为每个线程都会返回一些字符串值。 所以我的问题是如何决定可以保留的最大线程数? 而重要的问题是,如果我继续增加线程数量,但照顾堆大小的条件,是否会在线程数超过某个限制后开始降低性能?增加线程数是否会降低java的整体性能?

+0

大概。最好的方法是尝试;) – Tedil

+1

“Java并发实践”中的“8.2。调整线程池”一节有关于此主题的有用信息http://books.google.ru/books?id=EK43StEVfJIC&pg=PT186&lpg = PT186&dq = Sizing + Thread + Pools + java + concurrency + in + practice&source = bl&ots = un0Gx2sRlr&sig = q6gBylm5pFXWgdyB3bV6KcIQUsI&hl = en&sa = X&ei = LsRkU4vDHcGN4ATvx4C4Dw& ved = 0CEkQ6AEwBA – ka3ak

回答

1

那么,这样的问题的最佳答案是“这取决于”。但我可以肯定地指出,它取决于什么:)

  • 你在一个线程中所做的工作。
  • 代码是否已经在利用底层硬件的并行特性?
  • 整个代码是否存在瓶颈,比并行任务需要更多时间?

在JVM中获取线程基础结构是一个代价高昂的过程,当您谈论线程时,同步也会出现。让我们暂时忘记同步。即使如此,如果执行的任务比分配和管理线程的开销更低,我会说严格的NO到多线程。

  • 事情是多线程证明是一个福音是当你的首要任务是使网络电话,有许多这样的任务。

  • 另一个这样的要求是做一些独立的计算,如块式矩阵乘法。

注意:编译器现在是一个天做了一些优化,以提高你的代码的并行处理能力。但以正确的方式编码的更大责任取决于您。

例如:考虑下面的代码在数组中添加10个数字。

这似乎是添加数组元素的最佳方法。但低于实际利用处理器的并行处理能力:

total = a[0] = a[1] + a[2] + a[3] + a[4] + a[5] + a[6] + a[7] + a[8] + a[9]; 

明智的选择:)

+0

谢谢:)。这是一个非常有用的信息。 所以,我可以总结一下,并说:“是的,如果你不明智地选择它,可能会随着线程数量的增加而降低性能”? – Abhijit

+0

当然是的......大多数情况下,如果工作量较小,这种做法很糟糕。 当任务非常耗时并且可以并行完成时,这真的很不错 – dharam

+0

编译器能够完成您在笔记本身中指出的代码转换。手工做这些东西不是一个好主意 - 当然不是这种情况 – Voo

3

找出使用多少个线程的最好方法是凭经验。但你可以预先猜测;如果你正在做大量的阻塞IO,你会想要更多的线程。如果你根本没有做任何IO,而只是使用CPU,那么你理想的情况是不需要比内核多的线程。您还必须考虑同步开销,如果您需要大量同步,那么在多线程上运行该代码很可能不会提高性能。

同样,它在很大程度上取决于应用程序。这些都只是经验法则,你将不得不执行更详细的分析和一些测试运行实际上能够告诉你的应用程序。

+0

感谢您的信息, :) 我明白了事情,“在多个线程上运行该代码并不会提高性能。”但即使不提高性能,它是否会随着线程数量的增加而降低性能? – Abhijit

+0

@Abhijit如果你做错了,是的。如果你有太多的线程,你可能最终不得不做大量不必要的上下文切换,这在性能方面是非常昂贵的。 – Cubic

0

简单的答案是肯定的,因为线程之间的交换是相当昂贵的。您必须在换出正在等待的线程和其他线程可以获得某些CPU以及交换费用之间取得平衡。

例如,如果你有100个comsumer线程典型的生产者,我怀疑的吞吐量会比如果你有10

0

最有可能的是,这会降低整体性能要大得多。以下是一些需要考虑的事实:

  • 在大多数情况下,由于CPU /内核数量有限,可以同时运行的线程数量有限;
  • 将一个线程与WAITING状态一起激活一些其他线程(这是所谓的context switching的一部分)在CPU资源方面相当昂贵;
  • Amdahl定律它提供了问题的答案 - 线程数,CPU,部分“工作”之间的关系可以同时完成并产生加速。这里很难发布公式,所以我只留下wiki page link
相关问题