2014-01-22 29 views
5

(我一直沒能找到這個問題的答案在任何地方,很抱歉,如果這是一個已經被問了一個問題。)JAVA多線程來一次檢查幾個數字的素性比單線程

我需要檢查每個數字是否達到我的用戶指定的值是一個質數。因此,我蠻力檢查每個號碼最多的是價值(這是我在技術上希望爲用戶希望它是一樣大)是否通過檢查的方法素數

p%i==0 

是否爲真,其中p是每個奇數的用戶輸入值3顯然,一旦程序開始檢查非常大的數字,循環遍歷每個奇數到輸入值的一半就需要一段時間。由於這個限制,我的程序在當前狀態下大大減慢了它的「每秒鐘檢查次數」率,這意味着該程序可能需要很長時間才能完成大數目。

爲了稍微解決這個問題,我試圖執行多線程的主要檢查方面,如下:

int CPUs = Runtime.getRuntime().availableProcessors(); 
int acCPU = 0; 
//... 
Thread pCheckThread[] = new Thread[CPUs-1]; 
class pCheckRunnable implements Runnable{ 
    long pr; 
    int xp, yp; 
    pCheckRunnable(long prime){ 
     pr=prime; 
    } 
    public void run(){ 
     if(isPrime(pr)) 
      //Do stuff... 
    } 
} 
//... 
for(long i=1; i<valueEntered; i++){ 
    pCheckThread[acCPU] = new Thread(new pCheckRunnable(i)); 
    pCheckThread[acCPU].start(); 
    acCPU++; 
    if(acCPU>=CPUs){ 
    for(int t=0; t<pCheckThread.length; t++){ 
     try { 
     pCheckThread[t].join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
    acCPU = 0; 
    } 
} 

正如你所希望看到的,當時的想法是,以檢查幾個數字是否是總理在一次,每個檢查在單獨的線程中運行,最大線程數等於可用的處理器內核數量。

問題是,該程序似乎現在實際上運行較慢

這是我第一次嘗試多線程和並行處理的手,我可能只是犯了一些非常愚蠢的錯誤,或者我的代碼可能會在你的一些更有經驗的編程人員的意見中造成巨大的混亂,所以感覺自由告訴我,我是否犯過任何可能導致不穩定或腐敗的嚴重錯誤。

+0

一個小小的優化,你只需要檢查到輸入數字的平方根,達不到它的一半。 –

+0

@ user3224223:對我來說,你的多線程代碼太低級了。此外,據我所知,只有在前面的所有線程都完成之後,纔會啓動新線程:因此,如果只有8個線程中的一個仍在工作,那麼將會阻止其他7個線程完成任何工作。如果你有1000萬個數字要測試,你通常也不想開始1000萬個線程:你會開始測試8個線程,每個線程測試1 250 000個數字。 – TacticalCoder

+0

@ user3224223:您也可能想要使用* isProbablePrime *方法來快速丟棄所有合成數字。 – TacticalCoder

回答

3

最有可能的原因是工作單元(isPrime(p))相當小,啓動線程需要比計算本身更多的時間。

爲了提高性能,您應該將an ExecutorService的任務的number of threads = number of processors(高於該數字,您的線程將競爭CPU資源並且會適得其反)。然後,您將只創建一些線程並重用它們,從而節省線程創建的開銷。

一旦完成,您應該看到明顯的改進。然後,您可以嘗試對任務進行分組,並一次提交多個任務,以查看是否可以進一步提高性能。

因此,它看起來像:

ExecutorService executor = 
    Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 

for(long i=1; i<valueEntered; i++){ 
    executor.submit(new pCheckRunnable(i)); 
} 
executor.shutdown(); 
executor.awaitTermination(); 
+0

據我所知,如果你有一個超線程的P4處理器,它可能也是原因。我錯了嗎? –

+0

@Pisek是的 - 無論處理器的數量是多少,啓動線程都會帶來不可忽視的開銷。 – assylias

+0

我的意思是在某些系統中HT被認爲是處理器中的另一個「核心」。在這種情況下,AFAIK'Runtime.getRuntime()。availableProcessors()'可以獲得2倍的數量。 –