如何解决求和问题的并行实现返回意外结果
所以我正在学习和试验 java 并发包,在那里我发现了一个并行实现的数字相加。
我想尝试不同的方法,所以我混合了合并排序算法的并行实现,它是分治法和典型的数字加法。
代码如下:
class SequentialSum {
public static long sum(int[] numbers,int low,int high) {
long total = 0;
for (int i = low; i <= high; i++) total += numbers[i];
return total;
}
}
class ParallelSum {
private static final AtomicLong finalSum = new AtomicLong(0);
public static void parallelSum(int[] numbers,int high,int threads) {
if (threads <= 1) finalSum.addAndGet(SequentialSum.sum(numbers,low,high));
int middle = (low + high) / 2;
Thread left = new Thread(() -> parallelSum(numbers,middle,threads / 2));
Thread right = new Thread(() -> parallelSum(numbers,middle + 1,high,threads / 2));
left.start();
right.start();
}
public static long getoutput() {
return finalSum.get();
}
}
public class _3_ParallelSummation {
private static final int NUM_OF_THREADS = Runtime.getRuntime().availableProcessors();
private static final Random random = new Random();
private static final int ARRAY_LENGTH = 100_000_000;
public static void main(String[] args) throws InterruptedException {
int[] numbers = new int[ARRAY_LENGTH];
for (int i = 0; i < ARRAY_LENGTH; i++) numbers[i] = random.nextInt(10);
long t1 = System.currentTimeMillis();
long sum = SequentialSum.sum(numbers,ARRAY_LENGTH - 1);
long t2 = System.currentTimeMillis();
System.out.printf("Sum is: %d,completed in %d ms\n",sum,t2 - t1);
t1 = System.currentTimeMillis();
ParallelSum.parallelSum(numbers,ARRAY_LENGTH - 1,NUM_OF_THREADS);
t2 = System.currentTimeMillis();
Thread.sleep(1000);
System.out.printf("Sum is: %d,ParallelSum.getoutput(),t2 - t1);
}
}
我得到了意想不到的结果:
Sum is: 449963052,completed in 56 ms
Sum is: 3950670566,completed in 3 ms
[28.597s][warning][os,thread] Failed to start thread - _beginthreadex Failed (EACCES) for attributes: stacksize: default,flags: CREATE_SUSPENDED STACK_SIZE_ParaM_IS.
[28.598s][warning][os,flags: CREATE_SUSPENDED STACK_SIZE_ParaM_IS.
[28.601s][warning][os,flags: CREATE_SUSPENDED STACK_SIZE_ParaM_IS.
解决方法
合并排序中缺少 else 块
if (threads <= 1) {
finalSum.addAndGet(SequentialSum.sum(numbers,low,high));
}else {
int middle = (low + high) / 2;
Thread left = new Thread(() -> parallelSum(numbers,middle,threads / 2));
Thread right = new Thread(() -> parallelSum(numbers,middle + 1,high,threads / 2));
left.start();
right.start();
}
添加 else 块将修复代码。
您也可以使用 join()
left.join();
right.join();
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。