我正在做作业,并且在利用线程使程序尽可能快地运行方面遇到了麻烦。该作业是关于生成大量随机自回避游走(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)如何正确使用线程,使其在运行时不会出现任何错误?我可以在每个线程启动后加入它们,但这意味着没有一个线程可以同时运行,不是吗?如果我这样做,我还不如不使用线程。
任何帮助,将不胜感激!提前致谢。:)
繁星coding
相关分类