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

您所在的位置:网站首页 java多线程汇总结果 java多线程处理list,速度提升嗖嗖的!

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

2024-01-26 04:23| 来源: 网络整理| 查看: 265

目录

项目场景

问题描述

解决方案:

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

方法二:有返回值

最后

项目场景

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

问题描述

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

解决方案:

使用多线程线程池实现

方法一:没有返回值,直接在任务里完成计算 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的核心数 * 超线程数),命令见如下:

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

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

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

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

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3