多线程批量操作示例

导读:本篇文章讲解 多线程批量操作示例,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

无返回值的多线程批量操作

开启10个线程分段计算1到10000的和

public class Calculate implements Runnable {
    List<Integer> urlList ; //线程处理的数据
    int therdid ;//线程id

    public Calculate(List<Integer> urlList, int therdid) {
        this.urlList = urlList;
        this.therdid = therdid;
    }
    
    @Override
    public void run() {
        int number = 0;
        for (Integer key : urlList) {
            number += key;
        }
        System.out.println("线程:"+therdid+" 起始数字:"+urlList.get(0)+" 结束数字:"+urlList.get(urlList.size()-1)+" 和为:"+number);
    }
}
    public static void main(String[] args)  {
        //生成1到10000的数字放入map
        Map<Integer, Integer> map = new HashMap<>();
        IntStream.rangeClosed(1, 10000).forEach(i -> map.put(i,i));

        //将map里的数据平级分配给therad个线程,分配到list
        List<List<Integer>> list = new ArrayList<>();//存储各线程要执行的数据
        int therad = 10;//开10个线程
        int handleNum = map.size() / therad;//每个线程处理的数据量
        int theradcount = 0;//线程计数
        int dataCount = 0;
        List<Integer> li = new ArrayList<>();
        for (Integer key : map.keySet()) {
            li.add(key);
            theradcount += 1;
            dataCount += 1;
            if (list.size() == therad && dataCount == map.size()) {
                list.add(li);
            } else if (handleNum == theradcount) {
                theradcount = 0;
                List<Integer> newLi = new ArrayList<>();
                newLi.addAll(li);
                list.add(newLi);
                li.clear();
            }
        }

        //多线程去执行计算
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(therad + 1);
        for (int m = 0; m < list.size(); m++) {
            fixedThreadPool.execute(new Calculate(list.get(m), m));
        }
        //等待所有线程执行完关闭线程池
        fixedThreadPool.shutdown();
    }

输出:

线程:0 起始数字:1 结束数字:1000 和为:500500
线程:2 起始数字:2001 结束数字:3000 和为:2500500
线程:6 起始数字:6001 结束数字:7000 和为:6500500
线程:5 起始数字:5001 结束数字:6000 和为:5500500
线程:3 起始数字:3001 结束数字:4000 和为:3500500
线程:1 起始数字:1001 结束数字:2000 和为:1500500
线程:8 起始数字:8001 结束数字:9000 和为:8500500
线程:9 起始数字:9001 结束数字:10000 和为:9500500
线程:4 起始数字:4001 结束数字:5000 和为:4500500
线程:7 起始数字:7001 结束数字:8000 和为:7500500

有返回值的多线程批量操作

开启10个线程分段计算1到10000的和,且各线程返回自己的计算结果,汇总所有结果得到总的和

public class CalculateTask implements Callable<Integer> {
    List<Integer> urlList; //线程处理的数据
    int therdid;//线程id

    public CalculateTask(List<Integer> urlList, int therdid) {
        this.urlList = urlList;
        this.therdid = therdid;
    }
    
    @Override
    public Integer call() {
        int number = 0;
        for (Integer key : urlList) {
            number += key;
        }
        System.out.println("线程:" + therdid + " 起始数字:" + urlList.get(0) + " 结束数字:" + urlList.get(urlList.size() - 1) + " 和为:" + number);
        return number;
    }
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
        //生成1到10000的数字放入map
        Map<Integer, Integer> map = new HashMap<>();
        IntStream.rangeClosed(1, 10000).forEach(i -> map.put(i, i));

        //将map里的数据平级分配给therad个线程,分配到list
        List<List<Integer>> list = new ArrayList<>();//存储各线程要执行的数据
        int therad = 10;//开10个线程
        int handleNum = map.size() / therad;//每个线程处理的数据量
        int theradcount = 0;//线程计数
        int dataCount = 0;
        List<Integer> li = new ArrayList<>();
        for (Integer key : map.keySet()) {
            li.add(key);
            theradcount += 1;
            dataCount += 1;
            if (list.size() == therad && dataCount == map.size()) {
                list.add(li);
            } else if (handleNum == theradcount) {
                theradcount = 0;
                List<Integer> newLi = new ArrayList<>();
                newLi.addAll(li);
                list.add(newLi);
                li.clear();
            }
        }

        //将每个线程任务加入到calculateList中等待执行
        List<CalculateTask> calculateList = new ArrayList<>();
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(therad + 1);
        for (int m = 0; m < list.size(); m++) {
            calculateList.add(new CalculateTask(list.get(m), m));
        }

        //提交批量任务,开始多线程执行,每个线程执行完后结果返回到future
        List<Future<Integer>> future = fixedThreadPool.invokeAll(calculateList);
        Integer result = 0;
        for (Future<Integer> re : future) {
            result += re.get();
        }
        //等待线程运行完关闭线程池
        fixedThreadPool.shutdown();
        System.out.println("计算完成,1到10000的和是:" + result);
    }

输出:

线程:2 起始数字:2001 结束数字:3000 和为:2500500
线程:3 起始数字:3001 结束数字:4000 和为:3500500
线程:4 起始数字:4001 结束数字:5000 和为:4500500
线程:8 起始数字:8001 结束数字:9000 和为:8500500
线程:9 起始数字:9001 结束数字:10000 和为:9500500
线程:0 起始数字:1 结束数字:1000 和为:500500
线程:1 起始数字:1001 结束数字:2000 和为:1500500
线程:5 起始数字:5001 结束数字:6000 和为:5500500
线程:6 起始数字:6001 结束数字:7000 和为:6500500
线程:7 起始数字:7001 结束数字:8000 和为:7500500
计算完成,110000的和是:50005000

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80258.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!