微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

求和问题的并行实现返回意外结果

如何解决求和问题的并行实现返回意外结果

所以我正在学习和试验 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 举报,一经查实,本站将立刻删除。