簡體   English   中英

如何利用Java多線程來實現最大速度和最小錯誤?

[英]How can I utilize Java multi-threading for maximum speed and minimum errors?

我正在做作業,但在利用線程使程序盡可能快地運行時遇到了麻煩。 該作業是關於生成大量隨機自我規避步行(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崩潰。 我相信這是因為我的線程涉及到Hashmap中的插入,並且該錯誤是多個線程試圖同時更改同一Hashmap的結果。

2)將打印“總運行時間(以秒為單位)”,也就是我代碼的最后一行,而沒有我也想打印的Map信息。 不會有錯誤輸出,並且我不確定是什么原因導致出現此結果。

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的錯誤。 在發現的結果#2中,我得到了意外的結果,其中一些代碼根本沒有執行。

所以,我現在有兩個問題:

1)在不加入線程的情況下發現的結果#2中發生了什么? 為什么我的代碼的整個部分“跳過”執行?

但更重要的是:

2)如何正確使用線程,使它們在運行時不會出現任何錯誤? 我可以在每個線程啟動后加入它們,但這意味着沒有一個線程可以同時運行,不是嗎? 如果執行此操作,則可能不使用線程。

任何幫助,將不勝感激! 提前致謝。 :)

這是一個非常廣泛的問題,我不確定它是否適合該格式,但是無論如何我都會盡力回答。

不加入線程時發現的結果#2中發生了什么? 為什么我的代碼的整個部分“跳過”執行?

當您啟動一個線程時,它將在后台執行其代碼,但是啟動本身會很快返回。 加入線程時,您將暫停執行,直到完成加入線程為止。 如果沒有加入,則實際上是在最終循環中(可能仍在運行許多線程時)“按原樣”采樣執行結果。 因此,您錯過了那些結果。

2)如何正確使用線程,使它們在運行時不會出現任何錯誤? 我可以在每個線程啟動后加入它們,但這意味着沒有一個線程可以同時運行,不是嗎? 如果執行此操作,則可能不使用線程。

這是這樣一個問題廣泛,但我可以給一些亮點:

  • 使用的線程不要超過可用於CPU綁定任務的CPU線程
  • 最小化共享資源的並發修改。 所有這些線程是否真的需要修改Hashmap?
  • 查看生產者/消費者設計。 您可以有許多線程來生成您的隨機游走,而只有一個線程可以收集完成的游走。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM