ThreadUtil 多线程处理List,回调处理具体的任务
每次想多线程处理一个大的结果集的时候 都需要写一大堆代码,自己写了个工具类 方便使用
package com.guige.fss.common.util; import com.guige.fss.common.exception.BusinessException;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils; 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; /**
* Created by admin on 2018/6/5.
* @author 宋安伟
*/
public class ThreadUtil {
//创建定长线程池,初始化线程
private static Logger log = LoggerFactory.getLogger(ThreadUtil.class); /**
* 对List进行多线程处理(限制 对List只读 如果想修改List 可以处理完毕后把要修改或删除的List返回 多线程执行完后再修改或删除)
* @param list 要处理的List
* @param threadSize 用几个线程处理
* @param threadLoadback 处理的回调(具体业务员)
* @param <T> 每个回调的返回结果
* @param <V> List<V>的泛型
* @return
*/
public static <T,V>List<T> executorsTasks(final List<V> list,final int threadSize,final ThreadLoadback<T,V> threadLoadback){
// 开始时间
long start = System.currentTimeMillis();
// 总数据条数
int dataSize = list.size();
// 线程数
int threadNum = dataSize / threadSize + 1;
// 定义标记,过滤threadNum为整数
boolean special = dataSize % threadSize == 0;
// 创建一个线程池
ExecutorService exec = Executors.newFixedThreadPool(threadNum);
// 定义一个任务集合
List<Callable<T>> tasks = new ArrayList<Callable<T>>();
Callable<T> task = null;
List cutList = null; for (int i = 0; i < threadNum; i++) {
if (i == threadNum - 1) {
if (special) {
break;
}
cutList = list.subList(threadSize * i, dataSize);
} else {
cutList = list.subList(threadSize * i, threadSize * (i + 1));
}
// System.out.println("第" + (i + 1) + "组:" + cutList.toString());
final List listStr = cutList;
task = new Callable<T>() {
@Override
public T call() throws Exception {
// System.out.println(Thread.currentThread().getName() + "线程:" + listStr);
return (T) threadLoadback.load(listStr);
// return }
};
// 这里提交的任务容器列表和返回的Future列表存在顺序对应的关系
tasks.add(task);
}
List<Future<T>> resultsFuture = null;
try {
log.debug("线程任务执行开始:任务数"+tasks.size());
resultsFuture = exec.invokeAll(tasks);
List<T> results = new ArrayList<>();
for (Future<T> future : resultsFuture) {
T result=future.get();
if(result!=null) {
results.add(result);
}
}
return results; } catch (Exception e) {
e.printStackTrace();
throw new BusinessException(e.getMessage());
}finally {
// 关闭线程池
exec.shutdown();
log.debug("线程任务执行结束");
log.debug("执行任务消耗了 :" + (System.currentTimeMillis() - start) + "毫秒");
} } interface ThreadLoadback<T,V> {
T load(List<V> list) throws Exception;
} public static void main(String[] args) {
List<String> list = new ArrayList<>();
for(int i=0;i<1000;i++){
list.add("i="+i);
}
List<List<Integer>> resultList= ThreadUtil.executorsTasks(list, 10, new ThreadLoadback<List<Integer>, String>() {
@Override
public List<Integer> load(List<String> list) throws Exception {
List<Integer> result= new ArrayList<>();
for(String str:list){
str= str.replaceAll("i=","");
result.add(Integer.parseInt(str));
System.out.println(Thread.currentThread().getName()+"休息1秒");
Thread.sleep(1000L);
}
return result;
}
});
if(!CollectionUtils.isEmpty(resultList)){
List<Integer> integers = new ArrayList<>();
resultList.stream().forEach(items -> {
if (!CollectionUtils.isEmpty(resultList)) {
items.stream().forEach(item -> {
integers.add(item); });
}
}
);
integers.stream().forEach(item->System.out.println(item)); }
} }
ThreadUtil 多线程处理List,回调处理具体的任务的更多相关文章
- QT实现HTTP JSON高效多线程处理服务器
QT实现HTTP JSON高效多线程处理服务器 Legahero QQ:1395449850 现在一个平台级的系统光靠web打天下是不太现实的了,至少包含APP和web两部分,在早期APP直接访问we ...
- Nodejs真.多线程处理
前言 Threads à gogo 是nodejs 的原生模块,使用这个模块可以让nodejs 具备多线程处理功能 安装方法 npm install threads_a_gogo 下载测试源码 git ...
- JAVA回调机制(CallBack)详解
序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...
- 小兔JS教程(三)-- 彻底攻略JS回调函数
这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...
- iOS 键盘添加完成按钮,delegate和block回调
这个是一个比较初级一点的文章,新人可以看看.当然实现这个需求的时候自己也有一点收获,记下来吧. 前两天产品要求在工程的所有数字键盘弹出时,上面带一个小帽子,上面安装一个“完成”按钮,这个完成按钮也没有 ...
- JAVA回调机制解析
一.回调机制概述 回调机制在JAVA代码中一直遇到,但之前不懂其原理,几乎都是绕着走.俗话说做不愿意做的事情叫做突破,故诞生了该文章,算是新年的新气象,新突破! 回调机制是什么?其实回 ...
- 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比
C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...
- 嵌入式&iOS:回调函数(C)与block(OC)回调对比
学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...
- Java回调方法详解
回调在维基百科中定义为: 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用. 其目的是允许底层代码调用在高层定义的子程序. 举个例子可能更明白一些:以Androi ...
随机推荐
- CSS初始化设置
在网页开发时,由于浏览器默认加载的css样式使得页面显示的样式出现一些意想不到的意外样式,所以首先要进行css的初始化设置. 此外一些常用的样式,比如浮动等也可以放到初始化中备用.
- spring session实现集群中session共享
本文转自:http://dorole.com/1422/ 使用框架的会话管理工具,也就是本文要说的spring-session,可以理解是替换了Servlet那一套会话管理,既不依赖容器,又不需要改动 ...
- RocketMQ集群搭建
1.RocketMQ介绍 1.1. 简介 RocketMQ 是一款分布式.队列模型的消息中间件,具有以下特点: 能够保证严格的消息顺序 提供丰富的消息拉取模式 高效的订阅者水平扩展能力 实时的消息订阅 ...
- 【技术】正則表達式—匹配电话号码,网址链接,Email地址
#pragma mark - 正则匹配电话号码.网址链接.Email地址 + (NSMutableArray *)addHttpArr:(NSString *)text { //匹配网址链接 NSSt ...
- java虚拟机和Dalvik虚拟机
java虚拟机和Dalvik虚拟机的区别: java虚拟机Dalvik虚拟机 java虚拟机基于栈. 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多dalvik虚拟机是基于寄存器的 j ...
- NFS根文件系统
按照以前文档可以正确制作根文件系统,并且开发板可正确nfs挂测主机目录. 现只需修改bootargs,使内核启动时挂测文件系统即可.setenv bootargs mem=64M console=tt ...
- C++中的类继承之单继承&多继承&菱形继承
C++中的类继承之单继承&多继承&菱形继承 单继承是一般的单一继承,一个子类只 有一个直接父类时称这个继承关系为单继承.这种关系比较简单是一对一的关系: 多继承是指 一个子类有两个或 ...
- R语言两种方式求指定日期所在月的天数
R语言两种方式求指定日期所在月的天数 days_monthday<-function(date){ m<-format(date,format="%m& ...
- CMake 使用方法
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的 ...
- 7 款基于 JavaScript/AJAX 的文件上传插件
本文整理了7款基于JavaScript和AJAX的文件上传插件,这些插件基本上都能实现以下功能: 多文件上传 拖拽操作 实时上传进度 自定义上传限制 希望能为你的开发工作带来帮助. 1. jQuer ...