2016-04-26 26 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綁定的過程。這個規則是將每個內核的線程數增加四倍,除了超線程系統的情況以外,每個內核的線程數可以增加四倍。