对共享可变状态的非同步访问通常不顺利.
在您的计算计算中,有一个可变变量long total.当你启动线程时:
CalculatorThread ct1 = new CalculatorThread(start, end/2 , calc);
CalculatorThread ct2 = new CalculatorThread( (end/2) + 1, end, calc);
你在这两个线程之间共享可变的calc状态.在calc中没有任何同步,因此线程只会以随机时间间隔丢弃彼此的内存.
这是一个工作版本:
class ParallelSum {
public static long calcSum(long start, long end) {
long total = 0;
for(long i = start; i < end; i++) {
total += i;
}
return total;
}
public static class CalculatorThread extends Thread {
private long result = 0;
private long start;
private long end;
public CalculatorThread(long start, long end) {
this.start = start;
this.end = end;
}
@Override
public void run() {
result = calcSum(start, end);
}
public long getResult() {
return result;
}
}
public static void main(String[] args) throws InterruptedException {
int start = 1;
int end = 100000;
int endExcl = end + 1;
CalculatorThread ct1 = new CalculatorThread(start, endExcl/2);
CalculatorThread ct2 = new CalculatorThread(endExcl / 2, endExcl);
ct1.start();
ct2.start();
ct1.join();
ct2.join();
System.out.println(ct1.getResult() + ct2.getResult());
}
}
输出:
5000050000
附加说明:始终使用[包含,独占]范围索引.这大大降低了逐个出错的几率.此外,我已经通过一种方法替换了Calculation类:在方法内部,局部变量没有任何问题,并且可变状态越少越好.