2012-12-17 11 views
1

我正在編寫一些Java代碼時出現了一個非常奇怪的錯誤。如果我運行了一些並行代碼,我已經完成了它的運行,但是如果我在同一次運行中多次運行相同的代碼,那麼每次運行時都會變得越來越慢。使用複製運行時的Java線程

如果我將線程數從4增加到8,則每次迭代的減速都會更加劇烈。

每次運行都是完全獨立的,我甚至將運行時變量設置爲null以清除舊運行。所以我不知道什麼可能會放慢速度。我一直在使用Visual VM,它說.run()將所有的時間花費在「Self Time」或「Thread.init()」上,這是沒有用的。

一些代碼片段:

for (int r = 0; r < replicateRuns; ++r) { 
    startTime = System.nanoTime(); 
    result = newRuntime.execute(); 
    result = null; 
    System.out.println((System.nanoTime() - startTime)/1000000); 
    total += System.nanoTime() - startTime; 
} 

parentThread = this; 
    thread = new Thread[numberOfThreads]; 
    barrier = new CyclicBarrier(numberOfThreads); 

    for (int i = 0; i < numberOfThreads; i++) { 
     thread[i] = new Thread(new Runtime(parentThread, variation, delta, eta, i, 
       numberOfThreads), i + ""); 
     thread[i].start(); 
    } 

    for (int i = 0; i < numberOfThreads; i++) { 
     try { 
      thread[i].join(); 
      thread[i] = null; 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

因此,在爲什麼,如果我啓動Java應用程序很多次我拿到像樣的成績任何線索,但如果我運行中的多次同樣的啓動速度一切都會變慢,儘管據我所知我沒有任何東西,所以GC來了並清理它。

我正在使用線程局部變量,但從我讀過的所有清理線程本身設置爲空時。

乾杯的任何幫助!

編輯1:

感謝您的所有幫助。情節變厚了,在我的Windows桌面上(與我的MacBook相反),根本沒有問題,每個線程都運行良好,即使增加運行量也不會減速!在看了這一天之後,我會在早上第一次嘗試Eclipse MAT。

關於源代碼,我用MOEAD的並行版本擴展了MOEA框架,因此提供了許多依賴和類。 MOEA framework你可以找到我的課程here的來源。基本上迭代被重複調用,直到numberOfEvaulations達到設定值。

+2

爲了更快獲得更好的幫助,您應該嘗試創建[SSCCE](http://sscce.org/)。這樣,人們將能夠測試您的代碼,重現問題並可能發現問題。例如,如果不知道「新運行時(...)」是什麼,就很難推理你的問題。 – assylias

+0

我會嘗試發佈更多的代碼,但是有一個巨大的類層次結構,我不想用一層代碼來發送垃圾郵件。這更像是一個普遍的「我需要做更多的事情而不是一個線程」來清除它的問題。 – masterjonny

+1

這個想法是從你的代碼中提取一個複製行爲的最小可編譯示例。如果線程仍在運行,它將不會被垃圾收集。 – assylias

回答

1

我相信這裏的人們所說的問題是,你不是以正確的方式「停止」你的線索 - 有點說話。

根據我的經驗,最好的方法是將狀態存儲在線程中,存儲在布爾變量中。 isRunning。那麼你的循環內您測試狀態isRunning標誌,即

//inside the run method 
while(isRunning){ 
//your code goes here 
} 

這樣,你正在檢查的標誌的當前狀態,因此,當您將它設置爲「假」的循環的每次迭代,例如,您的自定義stop()方法。循環的下一次迭代將導致線程退出其run方法,從而結束線程的生命。從技術上講,現在它已經準備好被垃圾收集。它的內存將在不久的將來被釋放,因爲在代碼中沒有提到這個威脅掛在某處。

有更多來源顯示此方法,例如,檢出this discussion on LinkedIn

作爲一個側面說明它,看看究竟是什麼newRuntimeresult變量,它們的類和繼承等。否則,我們只能盡力猜測,實際上是什麼在你的代碼是怎麼回事是真正有用的。

+1

正如博羅所說,殺死線索或放寬參考不好,這是不好的,因爲如果線程還活着,它不會停止,即使你不保留參考。只要讓它完成執行,它就會自然死亡=)。另一方面,如果在執行過程中使用了一些同步資源,則可能會導致性能問題,因此每個線程都可能正在等待它。 –

0

你總是產生新的線程,永遠不會處置它們。 如果線程數量大於處理器內核數量,我們必須切換線程,這可能會使性能下降大約1000倍。 如果您正在使用Netbeans IDE,則在事件探查器中,您可以查看線程及其狀態。