我正在做作業,并且在利用線程使程序盡可能快地運行方面遇到了麻煩。該作業是關于生成大量隨機自回避游走(SAW)的。分配指南表示執行 1,000 個并發運行的線程,從而盡可能節省時間。每個線程內都存在一個嵌套的 for 循環。對于 n = 10 到 n = 40,程序生成 N_w 次行走。我的目標是使 N_w 盡可能大并產生更多的步行。我已經創建了 1,000 個線程,但我不確定是否正確利用它們來盡可能快地進行計算。SawGenerator 是一個擴展 Thread 的類,并包含一個嵌套的 for 循環來生成所有的遍歷。我嘗試通過創建 1,000 個 SawGenerators 并逐個啟動它們來生成 1,000 個線程,并將每個 SawGenerator 中的 N_w 設置為 500。for (int i = 0; i < 1000; i++) { SawGenerator mySawGenerator = new SawGenerator(); mySawGenerator.start();}for (Map.Entry<Integer, Double> entry : numSuccessfulWalks.entrySet()) { int curLength = entry.getKey(); System.out.println("SAW's of length: " + curLength); System.out.println(" numSuccessfulWalks(" + curLength + "): " + numSuccessfulWalks.get(curLength)); System.out.println(" <Rn^2>: " + totalEndSqDist.get(curLength)/numSuccessfulWalks.get(curLength)); System.out.println(" Fraction Perimeter: " + numSuccessfulWalks.get(curLength)/(1000*500)); }long endTime = System.currentTimeMillis();System.out.println("Total Runtime in Seconds: " + ((endTime-startTime) / 1000));然而,這給了我幾個不同的結果:1) 我的程序經常會因 ConcurrentModificationException 崩潰。我相信這是因為我的線程涉及到哈希圖的插入,并且錯誤是多個線程試圖同時更改同一個哈希圖的結果。2)“以秒為單位的總運行時間”,又名我的代碼的最后一行,將在沒有我也想在其之前打印的地圖信息的情況下打印。不會有錯誤輸出,我不確定是什么原因導致出現這種結果。3)我的程序將運行并完成所有計算,沒有任何問題。我認為這只發生在線程表現“理想”時。然后,我在啟動每個線程后添加了 join() 方法,這導致我的程序運行速度有點慢,但毫無疑問,它更加一致。我相信這是因為 join() 方法在開始下一個線程之前等待每個線程完成。for (int i = 0; i < 1000; i++) { SawGenerator mySawGenerator = new SawGenerator(); mySawGenerator.start(); try { mySawGenerator.join(); } catch (InterruptedException e) { e.printStackTrace(); }}現在,當我試圖加快程序速度時,我感覺自己陷入了僵局。在每個線程啟動后不使用 join() 會更快,因為它允許并行運行計算。但是,它可能會導致諸如 ConcurrentModificationException 之類的錯誤。在我發現的第二個結果中,我得到了一個意想不到的結果,我的一些代碼根本沒有執行。所以,我現在有兩個問題:1) 當我不加入我的線程時,我發現的結果中的#2 發生了什么?為什么我的代碼的整個部分“跳過”執行?但更重要的是:2)如何正確使用線程,使其在運行時不會出現任何錯誤?我可以在每個線程啟動后加入它們,但這意味著沒有一個線程可以同時運行,不是嗎?如果我這樣做,我還不如不使用線程。任何幫助,將不勝感激!提前致謝。:)
1 回答

繁星coding
TA貢獻1797條經驗 獲得超4個贊
這是一個非常廣泛的問題,我不確定它是否非常適合這種格式,但無論如何我都會盡力回答你。
當我不加入我的帖子時,我發現的第 2 個結果發生了什么?為什么我的代碼的整個部分“跳過”執行?
當您啟動一個線程時,它將在后臺執行其代碼,但啟動本身返回得相當快。當您加入一個線程時,您會暫停自己的執行,直到正在加入的線程完成。如果沒有加入,您實際上是在最終循環中“按原樣”對執行結果進行采樣,而此時許多線程可能仍在運行。因此,您會丟失這些結果。
2)如何正確使用線程,使其在運行時不會出現任何錯誤?我可以在每個線程啟動后加入它們,但這意味著沒有一個線程可以同時運行,不是嗎?如果我這樣做,我還不如不使用線程。
這是一個寬泛的問題,但我可以強調一些要點:
使用的線程數不要超過可用于 CPU 密集型任務的 CPU 線程數
最大限度地減少共享資源的并發修改。所有這些線程真的需要修改 Hashmap 嗎?
查看生產者/消費者設計。您可以有許多線程生成隨機游走,而只有一個線程收集完成的游走。
添加回答
舉報
0/150
提交
取消