java 多线程处理一个list的集合

问题描述

大家好,我的一个List<String>中有10W条记录,要把这个List的的内容拼接起来。我启动5个线程同时处理,每个线程处理2w条记录。然后把5个线程处理的内容拼接起来。 请大家给一个简单的demo。谢谢

解决方案

不用这么复杂,这样就好了..import java.util.ArrayList;import java.util.List;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class Test {public static void main(String[] args) {try {List<String> list = new ArrayList<>();for (int i = 0; i < 100; i++) {list.add(i + ",");}System.out.println(new Test().list2Str(list, 5));} catch (Exception e) {e.printStackTrace();}}public String list2Str(List<String> list, final int nThreads) throws Exception {if (list == null || list.isEmpty()) {return null;}StringBuffer ret = new StringBuffer();int size = list.size();ExecutorService executorService = Executors.newFixedThreadPool(nThreads);List<Future<String>> futures = new ArrayList<Future<String>>(nThreads);for (int i = 0; i < nThreads; i++) {final List<String> subList = list.subList(size / nThreads * i, size / nThreads * (i + 1));Callable<String> task = new Callable<String>() {@Overridepublic String call() throws Exception {StringBuffer sb = new StringBuffer();for (String str : subList) {sb.append(str);}return sb.toString();}};futures.add(executorService.submit(task));}for (Future<String> future : futures) {ret.append(future.get());}executorService.shutdown();return ret.toString();}}
解决方案二:
有个问题,如果5个线程有一个失败,其他线程就会阻塞哦
解决方案三:

解决方案四:
针对 @blackstreet 提出的内存溢出的问题,代码做出如下修改.1,多加一次list的遍历来预设StringBuffer的长度,而多的这次循环本身几乎没有性能开销(13000000次循环仅70ms左右,当然环境不同实际时间会有偏差)2,对参数list不进行subList操作,因为我们可以发现list在后续操作中是只读,不涉及并发带来的线程安全问题,所以循环时直接通过index来做取值区间判断.(奇怪的是,去除subList的操作似乎并没有对性能产生什么影响)3,关于StringBuilder和StringBuffer,13000000数据测试了几次,居然也没有什么差别.不解,可能是jvm默认调了优,也可能我测试数据不够..总之测试比较少,没有权威性,一切以实际为准.各位就姑且一看吧.public String list2Str(final List<String> list, final int nThreads) throws Exception {if (list == null || list.isEmpty()) {return null;}int len = 0;for (String str : list) {len += str.length();}StringBuffer ret = new StringBuffer(len);final int size = list.size();ExecutorService executorService = Executors.newFixedThreadPool(nThreads);List<Future<String>> futures = new ArrayList<Future<String>>(nThreads);try {for (int i = 0; i < nThreads; i++) {final int j = i;Callable<String> task = new Callable<String>() {@Overridepublic String call() throws Exception {int len = 0;for (int n = size / nThreads * j; n < size / nThreads * (j + 1); n++) {len += list.get(n).length();}StringBuffer sb = new StringBuffer(len);for (int n = size / nThreads * j; n < size / nThreads * (j + 1); n++) {sb.append(list.get(n));}return sb.toString();}};futures.add(executorService.submit(task));}for (Future<String> future : futures) {ret.append(future.get());}} finally {executorService.shutdown();}return ret.toString();}
解决方案五:
刚试了一下list 集合在13000000个for (int i = 0; i < 13000000; i++) {list.add("a" + i);} 直接用StringBuilder foreach append:每次稳定6.1秒多线程在11.7秒时内存jvm outof环境是在:win7 8个cpu核上运行意外地的我在运行单线程StringBuilder foreach append这种时,cpu的每个核都是在工作达到100%.谁解释下
解决方案六:
fork/join框架解决
解决方案七:
import java.util.ArrayList;import java.util.List;public class Test7 {public static void main(String[] args){List<String> list = new ArrayList<String>();for(int i=0;i<10;i++){list.add(i+"");}List<StringBuffer> sbs = new ArrayList<StringBuffer>();for(int i=0;i<5;i++){sbs.add(new StringBuffer());}Thread sumThread = new Thread(new Sum(sbs));for(int i=0;i<5;i++){ Thread thread = new Thread(new MyHander(list,i*2,i*2+2,sbs.get(i))); thread.start();}sumThread.start();}} class Sum implements Runnable{ private List<StringBuffer> sbs; public Sum(List<StringBuffer> sbs){ this.sbs =sbs; }public void run() {synchronized (this) { while(true){ if(MyHander.getCounter()<5){try {wait(100);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} }else{ break; } } StringBuffer value = new StringBuffer();for(int i=0;i<5;i++){value.append(sbs.get(i).toString());}System.out.println(value.toString());}} } class MyHander implements Runnable { private List<String> list; private int start; private int end; private StringBuffer sb; private static Integer counter=0; public MyHander(List<String> list,int start,int end,StringBuffer sb){ this.list =list; this.start = start; this.end = end; this.sb = sb; } public static Integer getCounter(){ return counter; } @Overridepublic void run() {for(int i=start; i<end;i++){ sb.append(list.get(i));}synchronized(counter){counter++; }} }
解决方案八:
你用这个类啊ArrayDeque,然后启动5个线程 每个线程内部循环2万次 去调用ArrayDeque.poll()方法就行了

时间: 2024-10-23 06:01:58

java 多线程处理一个list的集合的相关文章

java中一个商品列表集合简单问题

问题描述 java中一个商品列表集合简单问题 java中一个商品列表集合简单问题 java中一个商品列表集合简单问题 肯德可以理解为对象,java一切都是对象 那么可以理解为一个类吗可以理解为一个数组吗,可以理解为一种数据泪腺吗 解决方案 对象集合类是类,但不能说对象集合的对象是一个类,对象就是类的实例,和类是不等的.数组是指基本数据类型集合.比如int [] arrs = new int[]{},而List 等类创建的对象集只能称为集合.不能理解为数据类型.数据类型只有基本类型和引用类型.

为什么用 Java:一个 Python 程序员告诉你

每当我告诉别人我一直在用Java工作时,大家的反应都是: "纳尼!Java?为啥是Java?" 说实话,本人刚开始的时候也是同样的反应.但是由于Java的类型安全,执行性能和坚如磐石的工具,我渐渐地开始欣赏Java.同时我注意到,现在的Java已今非昔比--它在过去的10年间稳健地改善着. 缘何是Java? 假 设每天都用Java的想法还没有让君恶心到食不下咽,我在此重申Java已非你所了解的"吴下阿蒙"了.当Python, Ruby, 和Javascript在&q

java-怎么用Java做一个成绩管理系统?

问题描述 怎么用Java做一个成绩管理系统? Java实验课要做关于学生成绩管理系统的程序 之前学的比较浅 不知道从哪入手 希望大家能提供一些思路 题目如下: 数据库管理系统是一种常见的数据管理软件,数据库是按一定模式存储相关数据的集合.现将学生的成绩存储在education_management.mdb数据库的score表中,请编写一个数据库程序,实现录入学生成绩.自动计算成绩和学分.查询学生成绩的功能.score表中数据如下: 学号 课程编号 课程名称 学分 平时成绩 实验成绩 卷面成绩 综

jsp-怎么把JSON字符串转换成java字符串或数组或者集合

问题描述 怎么把JSON字符串转换成java字符串或数组或者集合 var chk_value =[]; $('input[name="zd_resourcecb"]:checked').each(function(){ chk_value.push($(this).val()); }); var chk_values = JSON.stringify(chk_value); jsp是这么写的 不过得到的是JSON字符串 ,我想要得到java类型的字符串或是数组什么的 解决方案 字符串反

线程-java创建一个输出流赋值为null的作用

问题描述 java创建一个输出流赋值为null的作用 public class Server { //服务端socket private ServerSocket serverSocket; //所有客户输出流 private List allOut; //线程池 private ExecutorService threadPool; /** * 构造方法,用于初始化 * / public Server() { try{ serverSocket=new ServerSocket(8088);

Java 多线程处理任务的封装

最近公司项目很多地方使用多线程处理一些任务,逻辑代码和java多线程处理代码混合在一起,造成代码的可读性超级差,现在把Java多线程相关的处理抽出来,方面代码中重复使用.抽的不好,欢迎大家拍砖 使用方法很简单,有两种使用方法 1.直接传递一批任务给到多线程处理方法,返回处理结果 代码如下: /**   * Created with IntelliJ IDEA.   * 测试多线程处理任务   * className: TaskMulThreadServiceTest   *   * @versi

一段代码搞懂关于Java中List、Set集合及Map的使用_java

Java中List.Set集合及Map的使用代码如下所示: package tingjizifu; import java.util.*; public class TongJi { /* * 使用Scanner从控制台读取一个字符串,统计字符串中每个字符出现的次数,要求使用学习过的知识完成以上要求 * 实现思路根据Set.List.Map集合的特性完成. */ public static void main(String[] args) { // 输入字符串 Scanner input = n

java swing 一个窗口打开新创口 加上go()程序就死掉了

问题描述 java swing 一个窗口打开新创口 加上go()程序就死掉了 import javax.swing.*; import java.awt.Rectangle;import java.awt.event.*; public class Swing7 extends JFrame implements ActionListener { JButton jb = new JButton(); public Swing7() { this.setTitle(""Java--&q

新官上任,转贴一篇:Java做一个最简单的通话程序

程序 Java中的网络编程是一个很重要的部分,也是其编程优越性的地方之一.在Java中有一个专门的Java.net类库来管理网络编程的有关方法. 下面先介绍在Java中怎样用socket进行客户与服务器通信.最后再介绍一个一个最简单的通话程序. 一.怎样用socket进行客户与服务器通信 在Java中用socket进行客户/服务器之间的通信编程.Socket是两个实体之间进行通信的有效端点.通过socket可以获得源IP地址和源端口.终点IP地址和终点端口.用户可以将多个socket连入同一个端