多线程分段求和

简介: 该代码实现了一个多线程计算求和的程序。`MyThread`类中,`sum`方法计算指定范围的和,`divide`方法将任务分块,`sunFirst`使用线程池并行计算各块的和,结果存入`list1`。通过`CountDownLatch`同步线程,所有线程完成后输出总和。测试用例展示了10个线程计算1到10000的和,表明多线程加速效果。注意线程数量与性能的关系,需权衡线程切换成本。

思路:先计算每个线程计算的数据范围,使用线程计数器,所有线程计算结束后累加

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.SynchronousQueue;

/**
 * @author Zing
 * @create 2022-11-07 14:17
 */
public class MyThread {
   
    private List list1 = new ArrayList();

    private List list2 = new ArrayList();

//    分段求和
    public long sum(long start,long n){
   
        long sum = 0;
        for(long i = start;i <= n;i++){
   
            sum+= i;
        }
        return sum;
    }

    public void sum(){
   
        long sum = 0;
        for (Object o : list1) {
   
            sum += (long) o;
        }
        System.out.println(sum);
    }

//    list2记录每个线程的第一个和最后一个数字
    public void divide(long n,long x){
   
        long block = n / x;
        long temp = block;
        long j = 1;
        for (long m = 1;m <= x;m++){
   
            list2.add(j);
            list2.add(temp);
            j = temp + 1;
            temp = block * (m + 1);
        }
    }

    public void sunFirst(long n,long x) throws InterruptedException {
   
        divide(n,x);
        CountDownLatch countDownLatch =new CountDownLatch(list2.size() / 2);
        for(int h = 1;h < list2.size();h+=2){
   
            int finalH = h;
            new Thread(()->{
   
                long realSum = sum((long) list2.get(finalH - 1),(long) list2.get(finalH));
                System.out.println("real sum" + finalH + ":" + realSum);
                list1.add(realSum);
                countDownLatch.countDown();
            }).start();
        }
        countDownLatch.await();
        System.out.println("success");
        sum();
    }


}

测试:

public class test {
   
    public static void main(String[] args) throws InterruptedException {
   

        MyThread myThread = new MyThread();
        myThread.sunFirst(10000,10);

    }
}

计算十亿暴力时间戳差为370,十个线程仅90,这不是最佳匹配,要考虑线程切换资源适配合适的线程数量,但是多线程始终比暴力快

相关文章
|
6月前
|
算法 测试技术 C++
【数据结构】【双堆】【滑动窗口】3013. 将数组分成最小总代价的子数组 II
【数据结构】【双堆】【滑动窗口】3013. 将数组分成最小总代价的子数组 II
|
Java
Java线程求和
Java线程求和
69 0
|
6月前
|
设计模式 算法 Java
【数据结构和算法】交替合并字符串
给你两个字符串word1和word2。请你从word1开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。返回合并后的字符串。
107 1
13:分段函数
13:分段函数
117 0
|
Java
如何计算线程数的最优值?——咱有公式
如何计算线程数的最优值?——咱有公式
226 0
如何计算线程数的最优值?——咱有公式
|
C++
201509-1 数列分段
201509-1 数列分段
69 0
201509-1 数列分段
|
人工智能 测试技术
7-2 数列分段
7-2 数列分段
70 0
累加思想与计数器思想
累加思想与计数器思想
128 0
|
算法 Go
使用自旋算法实现“两个线程轮流打印0到100奇偶数?”
本次循环不该打印时,让线程代码自旋;等待另外的线程递增而引起本线程再次进入业务代码。
|
安全 Java 算法
SOFAJRaft 线性一致读实现剖析 | SOFAJRaft 实现原理
Scalable Open Financial Architecture Stack 是蚂蚁金服自主研发的金融级分布式架构,包含了构建金融级云原生架构所需的各个组件,是在金融场景里锤炼出来的最佳实践。
945 0