Java多线程处理List数据

多线程数量的问题,一般情况下,多线程数量要等于机器CPU核数-1.

实例1:

解决问题:如何让n个线程顺序遍历含有n个元素的List集合

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 import org.apache.commons.lang3.ArrayUtils;
 4
 5 public class Test_4 {
 6     /**
 7      * 多线程处理list
 8      *
 9      * @param data  数据list
10      * @param threadNum  线程数
11      */
12     public synchronized void handleList(List<String> data, int threadNum) {
13         int length = data.size();
14         int tl = length % threadNum == 0 ? length / threadNum : (length
15                 / threadNum + 1);
16
17         for (int i = 0; i < threadNum; i++) {
18             int end = (i + 1) * tl;
19             HandleThread thread = new HandleThread("线程[" + (i + 1) + "] ",  data, i * tl, end > length ? length : end);
20             thread.start();
21         }
22     }
23
24     class HandleThread extends Thread {
25         private String threadName;
26         private List<String> data;
27         private int start;
28         private int end;
29
30         public HandleThread(String threadName, List<String> data, int start, int end) {
31             this.threadName = threadName;
32             this.data = data;
33             this.start = start;
34             this.end = end;
35         }
36
37         public void run() {
38             List<String> subList = data.subList(start, end)/*.add("^&*")*/;
39             System.out.println(threadName+"处理了"+subList.size()+"条!");
40         }
41
42     }
43
44     public static void main(String[] args) {
45         Test_4 test = new Test_4();
46         // 准备数据
47         List<String> data = new ArrayList<String>();
48         for (int i = 0; i < 6666; i++) {
49             data.add("item" + i);
50         }
51         test.handleList(data, 5);
52         System.out.println(ArrayUtils.toString(data));
53     }
54 }

实例2:

List多线程并发读取读取现有的list对象

 1 //测试读取List的线程类,大概34秒
 2 package com.thread.list;
 3
 4 import java.util.ArrayList;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8
 9 public class Main {
10
11     public static void main(String[] args) {
12
13         List<String> list = new ArrayList<String>();
14         Map<Long,Integer> map = new HashMap<Long,Integer>();
15
16         for(int i = 0;i<1000;i++){
17             list.add(""+i);
18         }
19
20         int pcount = Runtime.getRuntime().availableProcessors();
21         long start = System.currentTimeMillis();
22
23         for(int i=0;i<pcount;i++){
24
25            Thread t = new MyThread1(list,map);
26             map.put(t.getId(),Integer.valueOf(i));
27             t.start();
28             try {
29                 t.join();
30             } catch (InterruptedException e) {
31                 e.printStackTrace();
32             }
33            // System.out.println(list.get(i));
34         }
35         System.out.println("----"+(System.currentTimeMillis() - start));
36     }
37 }
38
39 //线程类
40 package com.thread.list;
41
42 import java.util.List;
43 import java.util.Map;
44
45 public class MyThread1 extends Thread {
46
47     private List<String> list;
48     private Map<Long,Integer> map;
49
50     public MyThread1(List<String> list,Map<Long,Integer> map){
51         this.list = list;
52         this.map = map;
53     }
54
55     @Override
56     public void run() {
57
58         int pcount = Runtime.getRuntime().availableProcessors();
59         int i = map.get(Thread.currentThread().getId());
60
61         for(;i<list.size();i+=pcount){
62             System.out.println(list.get(i));
63         }
64     }
65 }

实例3:

多线程分段处理List集合

场景:大数据List集合,需要对List集合中的数据同标准库中数据进行对比,生成新增,更新,取消数据
解决方案:

  1. List集合分段,
  2. 动态创建线程池newFixedThreadPool
  3. 将对比操作在多线程中实现

 1 public static void main(String[] args) throws Exception {
 2
 3         // 开始时间
 4         long start = System.currentTimeMillis();
 5         List<String> list = new ArrayList<String>();
 6
 7         for (int i = 1; i <= 3000; i++) {
 8             list.add(i + "");
 9         }
10         // 每500条数据开启一条线程
11         int threadSize = 500;
12         // 总数据条数
13         int dataSize = list.size();
14         // 线程数
15         int threadNum = dataSize / threadSize + 1;
16         // 定义标记,过滤threadNum为整数
17         boolean special = dataSize % threadSize == 0;
18
19         // 创建一个线程池
20         ExecutorService exec = Executors.newFixedThreadPool(threadNum);
21         // 定义一个任务集合
22         List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
23         Callable<Integer> task = null;
24         List<String> cutList = null;
25
26         // 确定每条线程的数据
27         for (int i = 0; i < threadNum; i++) {
28             if (i == threadNum - 1) {
29                 if (special) {
30                     break;
31                 }
32                 cutList = list.subList(threadSize * i, dataSize);
33             } else {
34                 cutList = list.subList(threadSize * i, threadSize * (i + 1));
35             }
36             // System.out.println("第" + (i + 1) + "组:" + cutList.toString());
37             final List<String> listStr = cutList;
38             task = new Callable<Integer>() {
39
40                 @Override
41                 public Integer call() throws Exception {
42                     System.out.println(Thread.currentThread().getName() + "线程:" + listStr);
43                     return 1;
44                 }
45             };
46             // 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
47             tasks.add(task);
48         }
49
50         List<Future<Integer>> results = exec.invokeAll(tasks);
51
52         for (Future<Integer> future : results) {
53             System.out.println(future.get());
54         }
55
56         // 关闭线程池
57         exec.shutdown();
58         System.out.println("线程任务执行结束");
59         System.err.println("执行任务消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
60     }

原文地址:https://www.cnblogs.com/huangdabing/p/9251598.html

时间: 2024-08-01 13:32:41

Java多线程处理List数据的相关文章

[z]protobuf实现c++与java之间的数据传递,beancopy数据到前台

[z]http://blog.csdn.net/xhyzdai/article/details/46684335 定义proto文件 [plain] view plain copy option java_package = "com.wy.web"; message my_message{ required string startedTime =1; required string version=2; required double configuredCapacity=3; r

java获取天气预报数据

获取天气预报数据 对于做web项目有天气数据的需求,这个服务很合适: WebXml.com.cn 2400多个城市天气预报Web服务,包含2300个以上中国城市和100个以上国外城市天气预报数据.数据每2.5小时左右自动更新一次,准确可靠.提供webservice 接口,主连接:http://webservice.webxml.com.cn/WebServices/WeatherWS.asmx/ 方法调用说明如下: (1)getRegionCountry :获得国外国家名称和与之对应的ID 说明

Jvm基础-Java运行时数据区

最近在看<深入理解Java虚拟机>,里面讲到了Java运行时数据区,这是Jvm基本知识,把读书笔记记录在此.这些知识属于常识,都能查到的,如果我有理解不对的地方,还请指出. 首先把图贴上来,图来自JVM Runtime Data Areas(运行时数据区),感谢. 由上图可知,Java运行时数据区域包括程序计数器.Java虚拟机栈.本地方法栈.Java堆.方法区. 1. 程序计数器 程序计数器用来记录下一条字节码指令,因为CPU是要轮转的,在切换回来之后,Java能够找到下一条要执行的指令.如

[原]使用Fiddler捕获java的网络通信数据

[原]使用Fiddler捕获java的网络通信数据 System.setProperty("http.proxySet", "true"); System.setProperty("http.proxyHost", "127.0.0.1"); System.setProperty("http.proxyPort", "8888");

as3+java+mysql(mybatis) 数据自动工具(七) - 完结

autoscript packed 文件地址:http://pan.baidu.com/s/1dDvgcO5 如果需要项目源码的话,可以留下邮箱,先声明一下,该工具主要是为了实现自动同步输出代码类文件的功能,所以代码写得并不是很规范什么的,没太大的参考意义,主要还是工具的实用性. 数据类和常量的配置基本就是前面所说明的那些了,现在来说一下怎么执行配置文件.执行配置文件需要写一个批处理文件,格式如下 java -classpath ./lib/*; AutoScript -? 这是一个执行 jav

深入理解Java运行时数据区

前情回顾 在本专栏的前12篇博客中, 我们主要大致介绍了什么是JVM, 并且详细介绍了class文件的格式. 对于深入理解Java, 或者深入理解运行于JVM上的其他语言, 深入理解class文件格式都是必须的. 如果读者对class文件的格式不是很熟悉, 在阅读本博客下面的文章之前, 建议先读一下前面的12篇博客, 或者参考其他资料, 熟悉class文件的格式. 在深入理解Java虚拟机到底是什么 这篇博客中, 我们有提到过, JVM就是一个特殊的进程, 我们执行的java程序, 都运行在一个

Java运行时数据区域划分

Java运行时数据区域划分 Java JVM 内存 堆 栈 1. 概述 对于Java程序员来说,在虚拟机自动内存管理机制下,不容易出现内存泄漏和内存溢出现象.但如果不了解虚拟机是如何使用内存的,一旦出现了内存泄漏和溢出方面的问题,那么排错就无从下手了. 2. 运行时数据区域 Java虚拟机在执行Java程序的过程中会将它所管理的内存划分为若干个不同的数据区域,如下图所示. 2.1. 程序计数器 程序计数器(Program Counter Register):是一块较小的内存空间,可以看做是当前线

JAVA的JSON数据包装-博客园老牛大讲

一.什么是json呢? {     "id":"1",     "username":"老牛大讲堂",     "password":"123" } 这就是json数据.用来和页面(HTMl)进行通信的. 二.通信为什么用json呢? 没有为啥,因为都用json.前端也好,后端也好,都用json数据传输. 三.java怎样把数据包装成json数据? 第一步:导入jar包.jar包自己下吧

as3+java+mysql(mybatis) 数据自动工具(四)

现在介绍一下只配置 as3 与 java 公用的数据类,这种配置一般是该数据类只需要在 as3 与 java 之间转换,跟数据库没有关系.比如在客户端与服务端的数据交换中,需要定义一个统一返回请求的数据类 ResultVO,包含一个属性 result(bool) 表示请求是否成功,另一个属性为 data(object) 表示该请求的返回数据,很明显数据类跟数据库是没有关系的,如果用前一篇介绍的配置就会生成多余的建表数据,而且某些数据类型也不能很好的支持. 这种数据类就可以用另一种配置,跟前一篇介