美文网首页
如果用给你一个Int数组很多值怎么求和

如果用给你一个Int数组很多值怎么求和

作者: 任笙_8b8c | 来源:发表于2021-04-23 14:27 被阅读0次

一般肯定是用for循环再累加,但是肯定不是最优解.
可以用多线程切片执行,一个线程执行一段 最后再累加
代码如下:

 @RequestMapping("/intsum")
    public Long intsum() {

        int[] array = new int[101];
        long s = System.currentTimeMillis();
        long sum = 0;

        // 第一种 int数组求和 累加操作
        for (int i = 0; i < array.length; i++) {
            array[i] = i;
            sum += array[i];
        }
        long start = System.currentTimeMillis();
        System.out.println(start - s);

        //第二种 sum()开启多线程执行
        long sum2 = sum(array);
        long end = System.currentTimeMillis();
        long cost = end - start;
        //      System.out.println(sum);
        //      System.out.println(sum2 == sum);
        System.out.println("sum:" + sum + ";equals:" + (sum2 == sum) + ";cost:" + cost);

        return sum;
    }



    static public long sum(final int[] array) {
        if (array == null || array.length == 0) {
            throw new IllegalArgumentException("array length must greater than 0");
        }


        final RuntimeData rd = new RuntimeData();
        //返回线程的数量 默认是17个
        int threadCount = rd.getThreadCount(array);
        System.out.println("thread count:" + threadCount);
        //每线程计算的数组元素个数
        final int lenPerThread = array.length / threadCount;
        //              System.out.println(lenPerThread);
        for (int i = 0; i < threadCount; i++) {
            final Integer index = i;  //可以被赋值多次 每次的index都不一样
            int i1 = index.hashCode();
            System.out.println(i1 + "值");

            //使用lambda表达式简化多线程实现
            new Thread(() -> {  //实现runnable接口的实现类
                System.out.println("第" + (index + 1) + "个线程开始执行");
                long s = 0;
                int start = index * lenPerThread;
                int end = start + lenPerThread;
                for (int j = start; j < end; j++) {
                    s += array[j];
                }
                //同步代码块执行完毕就会释放cpu的执行权
                synchronized (rd) {
                    rd.sum += s;
                    rd.finishThreadCount++;
                }
            }).start();


        }

        //余下的array元素
        int remain = array.length % threadCount;
        System.out.println("remain element count:" + remain);
        long s = 0;
        for (int i = array.length - remain; i < array.length; i++) {
            s += array[i];
        }
        synchronized (rd) {
            rd.sum += s;
        }

        //这里意思是如果线程数 不等于执行完的线程数 那就是还没执行完 一直睡眠
        while (rd.finishThreadCount != threadCount) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
                break;
            }
        }
        return rd.sum;
    }


}
/**
 * 保存运行时的相关数据
 *
 */
class RuntimeData {
    //保存和
    long sum;
    //默认线程数
    int defThreadCount = 10;
    //已经执行完成的线程数
    int finishThreadCount;

    /**
     * 根据数据长度获取线程数,线程数不会大于数组的长度。
     * @param array
     * @return
     */
    public int getThreadCount(int[] array) {
        if (array.length < defThreadCount) {
            return array.length;
        }
        return defThreadCount;
    }

}

相关文章

网友评论

      本文标题:如果用给你一个Int数组很多值怎么求和

      本文链接:https://www.haomeiwen.com/subject/nxmcrltx.html