每次想多线程处理一个大的结果集的时候 都需要写一大堆代码,自己写了个工具类 方便使用

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,回调处理具体的任务的更多相关文章

  1. QT实现HTTP JSON高效多线程处理服务器

    QT实现HTTP JSON高效多线程处理服务器 Legahero QQ:1395449850 现在一个平台级的系统光靠web打天下是不太现实的了,至少包含APP和web两部分,在早期APP直接访问we ...

  2. Nodejs真.多线程处理

    前言 Threads à gogo 是nodejs 的原生模块,使用这个模块可以让nodejs 具备多线程处理功能 安装方法 npm install threads_a_gogo 下载测试源码 git ...

  3. JAVA回调机制(CallBack)详解

    序言 最近学习java,接触到了回调机制(CallBack).初识时感觉比较混乱,而且在网上搜索到的相关的讲解,要么一言带过,要么说的比较单纯的像是给CallBack做了一个定义.当然了,我在理解了回 ...

  4. 小兔JS教程(三)-- 彻底攻略JS回调函数

    这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...

  5. iOS 键盘添加完成按钮,delegate和block回调

    这个是一个比较初级一点的文章,新人可以看看.当然实现这个需求的时候自己也有一点收获,记下来吧. 前两天产品要求在工程的所有数字键盘弹出时,上面带一个小帽子,上面安装一个“完成”按钮,这个完成按钮也没有 ...

  6. JAVA回调机制解析

    一.回调机制概述     回调机制在JAVA代码中一直遇到,但之前不懂其原理,几乎都是绕着走.俗话说做不愿意做的事情叫做突破,故诞生了该文章,算是新年的新气象,新突破!     回调机制是什么?其实回 ...

  7. 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比

    C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...

  8. 嵌入式&iOS:回调函数(C)与block(OC)回调对比

    学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...

  9. Java回调方法详解

    回调在维基百科中定义为: 在计算机程序设计中,回调函数,是指通过函数参数传递到其他代码的,某一块可执行代码的引用. 其目的是允许底层代码调用在高层定义的子程序. 举个例子可能更明白一些:以Androi ...

随机推荐

  1. mysql按年度、季度、月度、周、日统计查询的sql语句

    本文介绍一些mysql中用于查询的sql语句,包括按年度.季度.月度.周.日统计查询等,有需要的朋友,可以参考下. 一.年度查询 查询 本年度的数据   SELECT * FROM blog_arti ...

  2. sizeof数据对齐问题

    #include <iostream> using namespace std; struct A1 { int a; static int b; }; struct A2 { int a ...

  3. 细数JDK里的设计模式<转>

    这也是篇老文了,相信很多人也看过.前面那些废话就不翻译了,直接切入正题吧~ 结构型模式: 适配器模式: 用来把一个接口转化成另一个接口. java.util.Arrays#asList() javax ...

  4. Tomcat配置 设置启动参数,点击startup.bat启动

    catalina.batrem ---------------------------------------------------------------------------rem Set J ...

  5. JavaScrip——练习(做悬浮框再进一步:悬浮窗后缀悬浮窗——用this.className)

    对悬浮窗进一步改进: 用this.className 可以省略script <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitio ...

  6. 专题实验 Storage structure 物理存储

    物理存储结构主要是指: extent的分配, 以及datablock 存储相关, 置于tablespace, segment 都是逻辑结构. tablespace : 逻辑结构, 没有实际物理存储. ...

  7. 自己写的jQuery 左右选择框,大家多多指教!

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML> <HEAD ...

  8. C语言中预处理器的相关知识:

    预处理过程时,会做以下事情或着更多: 将所有的#define删除,并且展开所有的宏定义: 处理所有条件编译指令,如#if,#ifdef等: 处理#include预编译指令,将被包含的文件插入到该预编译 ...

  9. struts2将数据通过Json格式显示于EasyUI-datagrid数据表格

    1.搭建ssh开发环境 2.写好Dao.service等方法 3.建立DTO数据传输对象: package com.beichende.sshwork.user.web.dto; import jav ...

  10. bootstrap 标签页tab切换js(含报错原因)

    booststrap 标签页的tab切换,相信大家已经都很熟悉了,在boot官网示例以及其他网站已经很多罗列相关代码的了,这里就不赘述了.这里主要贴下让boot标签页默认显示哪个标签页的js. 主要留 ...