2016-04-26 31 views
1

我们使用的是Java 7并且正在开发多线程数据处理应用程序。由于某些限制,我们不使用spark或任何其他map-reduce方法来解决此问题。这个项目的想法是最大化使用多线程的应用程序的性能。Java线程数量>内核数量和垃圾回收数量

我的理解是,在任何给定的点上,考虑到CPU除了OS之外没有其他任何东西运行,同时工作的线程数量将等于CPU提供的超线程数量。但是有一些java GC可以随时使用。我们也必须考虑这一点。

此外,我知道,如果我创建更多的线程,然后实际上会降低性能,因为花费在上下文切换上的时间。

问题是考虑所有这些事情并创建适当数量的线程的最佳方式是什么。任何想法或思考过程?我应该考虑其他过程吗?

回答

3

的问题是什么将考虑所有这些事情,创建线程

我会使用Java 8中可以实现这个要求的适当数量的最佳途径。例如

Results result = listOfWork.parallelStream() 
          .map(t -> t.doWork()) 
          .collect(Collectors.reduce(.....)); 

但是,如果您被困在Java 7上,您可以使用ExecutorService。

int procs = Runtime.getRuntime().availableProcessors(); 
ExecutorService es = Executors.newFixedThreadPool(procs); 

但是有java的GC将踢在飘飞

除非你使用的CMS,它不会在同一时间踢,所以它不”无论这些线程在做什么(在调整线程池方面)

是否有任何其他进程需要考虑?

如果您在使用CPU的机器上有其他进程,那么您应该考虑它们。

+2

那么,fork-join框架在Java 7上是可用的。 –

+0

@SleimanJneidi fork-join可用,但使用正确很痛苦。如果你想使用Fork-Join,我强烈建议使用Java 8来为你做这件事。即不要直接使用它,除非你真的知道你在做什么。例如如果你想用fork-join矩阵乘法,请复制Doug Lea的实现。 –

+2

确实如此,但它比fixedThreadPool更具可扩展性我想 –

0

我其实在这最后一学期做了研究。在使用线程时,提高CPU限制进程性能的一个很好的经验法则是使用相同数量的线程作为内核,除非是超线程系统,在这种情况下,应该使用两倍的内核。可以得出的另一个经验法则是I/O绑定的过程。这个规则是将每个内核的线程数增加四倍,除了超线程系统的情况以外,每个内核的线程数可以增加四倍。