文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

java多线程处理list,速度提升嗖嗖的!

2023-09-12 05:43

关注

目录

项目场景

问题描述

解决方案:

方法一:没有返回值,直接在任务里完成计算

方法二:有返回值

最后


项目场景

前台通过模板批量上传数据到后台


问题描述

后台使用常规方法处理数据,效率低下


解决方案:

使用多线程线程池实现

方法一:没有返回值,直接在任务里完成计算

package com.lwk.test;import java.util.ArrayList;import java.util.List;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class ThreadPoolExample {    public static void main(String[] args) throws InterruptedException {        // 创建一个包含 10 个线程的线程池        ExecutorService executorService = Executors.newFixedThreadPool(10);        // 创建一个包含 10000 个元素的 List        List list = new ArrayList<>();        for (int i = 0; i < 10001; i++) {            list.add(i);        }        // 将 List 分成 10 个子 List,每个子 List 包含 1000 个元素        List> subLists = new ArrayList<>();        int subListSize = 1000;        for (int i = 0; i < list.size(); i += subListSize) {            subLists.add(list.subList(i, Math.min(i + subListSize, list.size())));        }        // 提交每个子 List 的处理任务给线程池        for (List subList : subLists) {            executorService.submit(new Task(subList));        }        // 等待线程池中所有任务执行完毕        executorService.shutdown();        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);        // 打印处理结果        System.out.println("List size: " + list.size());        System.out.println("Sum of elements: " + Task.getSum());    }    static class Task implements Runnable {        private List list;        private static long sum = 0;        public Task(List list) {            this.list = list;        }        @Override        public void run() {            long subSum = 0;            for (int i : list) {                subSum += i;            }            synchronized (Task.class) {                sum += subSum;            }        }        public static long getSum() {            return sum;        }    }}

方法二:有返回值

除了创建线程池和分割 List 的过程外,主要的变化是将 Task 类改为实现 Callable 接口,并返回子 List 的和。使用 CompletionService 提交任务和获取任务执行结果,从而减少了线程池等待时间提高执行效率。最后,将每个子 List 的和累加起来,打印处理结果。

package com.lwk.test;import java.util.ArrayList;import java.util.List;import java.util.concurrent.*;public class ThreadPoolExample2 {    public static void main(String[] args) throws InterruptedException, ExecutionException {        // 创建一个包含 10 个线程的线程池        ExecutorService executorService = Executors.newFixedThreadPool(10);        // 创建一个 CompletionService,用于提交任务和获取任务执行结果        CompletionService completionService = new ExecutorCompletionService<>(executorService);        // 创建一个包含 10000 个元素的 List        List list = new ArrayList<>();        for (int i = 0; i < 10001; i++) {            list.add(i);        }        // 将 List 分成 10 个子 List,每个子 List 包含 1000 个元素        List> subLists = new ArrayList<>();        int subListSize = 1000;        for (int i = 0; i < list.size(); i += subListSize) {            subLists.add(list.subList(i, Math.min(i + subListSize, list.size())));        }        // 提交每个子 List 的处理任务给 CompletionService        for (List subList : subLists) {            completionService.submit(new Task(subList));        }        // 获取每个任务的执行结果,并将结果累加起来        long sum = 0;        for (int i = 0; i < subLists.size(); i++) {            Future future = completionService.take();            sum += future.get();        }        // 打印处理结果        System.out.println("List size: " + list.size());        System.out.println("Sum of elements: " + sum);        // 关闭线程池        executorService.shutdown();    }    static class Task implements Callable {        private List list;        public Task(List list) {            this.list = list;        }        @Override        public Long call() throws Exception {            long subSum = 0;            for (int i : list) {                subSum += i;            }            return subSum;        }    }}

最后

如果改为项目中使用的话,需要将 【创建一个包含 10000 个元素的 List】改为自己的数据集即可!

需要注意的是:在使用线程池时,需要选择合适的线程池大小,以避免创建过多的线程导致系统资源耗尽!

还有一点:也不要盲目的去开多个线程。如果你的服务器是单cpu单核开多线程反而会增加上下文损耗,从而降低程序执行效率。能开多少个线程,理论是这样计算的:逻辑cpu个数 = (物理cpu个数 * 每个cpu的核心数 * 超线程数),命令见如下

查看物理cpu个数,也就是实物cpu的个数

cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

查看每个cpu的core,也就是常说的核心数

cat /proc/cpuinfo| grep "cpu cores"| uniq

今天的分享就到这里了,如果问题欢迎留言指正! 

来源地址:https://blog.csdn.net/kevinlcsdn/article/details/129381763

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯