网站首页 > java教程 正文
线程池优化导入Excel功能核心代码如下:
StopWatch stopWatch = new StopWatch("任务");
stopWatch.start("处理数据");
int totalSize = dataList.size();
LOG.info("{},线程开始, 条数:{}", totalSize);
List<Future> fuList = new ArrayList<>();
/**
* 设置线程池:
* 线程池核心线程数
* 线程池最大线程数
* 空闲线程存活时间(过期回收)
* LinkedBlockingQueue: 阻塞队列
* 拒绝处理策略:
* ThreadPoolExecutor.AbortPolicy():被拒绝后抛出RejectedExecutionException异常
* ThreadPoolExecutor.CallerRunsPolicy():被拒绝后给调用线程池的线程处理
* ThreadPoolExecutor.DiscardOldestPolicy():被拒绝后放弃队列中最旧的未处理的任务
* ThreadPoolExecutor.DiscardPolicy():被拒绝后放弃被拒绝的任务(当前新添加的任务)
*
*/
ThreadPoolExecutor pool = new ThreadPoolExecutor(
8, 17, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(100), new ThreadPoolExecutor.DiscardOldestPolicy());
int leftCount = totalSize % batchSize;
int last = 0;
for (int i = 0; i < totalSize / batchSize; i++) {
int start = i * batchSize;
last = start + batchSize;
final List subList = dataList.subList(start, last);
Future<?> f = pool.submit(new Runnable() {
@Override
public void run() {
doBusiness(subList,user, poetryTypeService, authorService, poetryService);
}
});
fuList.add(f);
}
final List leftList = dataList.subList(last, last + leftCount);
if (leftList.size() > 0) {
LOG.info("left data size:{}", leftList.size());
Future<?> f = pool.submit(new Runnable() {
@Override
public void run() {
//你的业务逻辑
doBusiness(leftList,user, poetryTypeService, authorService, poetryService);
}
});
fuList.add(f);
}
for (Future fu : fuList) {
fu.get();
}
pool.shutdown();
stopWatch.stop();
LOG.info("导入成功,总条数:{},{}", totalSize, stopWatch.prettyPrint());
调用方式:
ImportTask importTask = new ImportTaskMngImpl(list, user, poetryTypeService, authorService, poetryService);
importTask.exec();
使用easypoi实现导入Excel功能:
List<PoetryDTO> list =ExcelImportUtil.importExcel(file.getInputStream(),PoetryDTO.class, params);
在使用线程池之前,需要先了解线程池!
创建线程池有俩种方式:通过Executors类提供的方法和通过ThreadPoolExecutor类自定义。
一、通过Executors类提供的方法
Executors类有四种线程池,分别是:
1.创建一个可缓存的线程池newCachedThreadPool
2.创建一个固定大小的线程池newFixedThreadPool
3.创建一个周期性的线程池newScheduledThreadPool
4.创建一个单线程的线程池newSingleThreadExecutor
二、通过ThreadPoolExecutor类自定义
ThreadPoolExecutor类提供了4种构造方法,可根据需要来自定义一个线程池。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
// 省略...
}
参数说明:
1.corePoolSize:核心线程数,线程池中始终存活的线程数。
2.maximumPoolSize: 最大线程数,线程池中允许的最大线程数。
3.keepAliveTime: 存活时间,线程没有任务执行时最多保持多久时间会终止。
4.unit: 单位,参数keepAliveTime的时间单位,7种可选。
参数 | 描述 |
TimeUnit.DAYS | 天 |
TimeUnit.HOURS | 小时 |
TimeUnit.MINUTES | 分 |
TimeUnit.SECONDS | 秒 |
TimeUnit.MILLISECONDS | 毫秒 |
TimeUnit.MICROSECONDS | 微妙 |
TimeUnit.NANOSECONDS | 纳秒 |
5.workQueue: 一个阻塞队列,用来存储等待执行的任务,均为线程安全,7种可选。
参数 | 描述 |
ArrayBlockingQueue | 一个由数组结构组成的有界阻塞队列。 |
LinkedBlockingQueue | 一个由链表结构组成的有界阻塞队列。 |
SynchronousQueue | 一个不存储元素的阻塞队列,即直接提交给线程不保持它们。 |
PriorityBlockingQueue | 一个支持优先级排序的无界阻塞队列。 |
DelayQueue | 一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素。 |
LinkedTransferQueue | 一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。 |
LinkedBlockingDeque | 一个由链表结构组成的双向阻塞队列。 |
较常用的是LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。
6.threadFactory: 线程工厂,主要用来创建线程,默及正常优先级、非守护线程。
7.handler:拒绝策略,拒绝处理任务时的策略,4种可选,默认为AbortPolicy。
参数 | 描述 |
AbortPolicy | 拒绝并抛出异常。 |
CallerRunsPolicy | 重试提交当前的任务,即再次调用运行该任务的execute()方法。 |
DiscardOldestPolicy | 抛弃队列头部(最旧)的一个任务,并执行当前任务。 |
DiscardPolicy | 抛弃当前任务。 |
线程池的执行规则
当线程数小于核心线程数时,创建线程;
当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列;
当线程数大于等于核心线程数,且任务队列已满:若线程数小于最大线程数,创建线程,若线程数等于最大线程数,抛出异常,拒绝任务。
建议使用自定义类ThreadPoolExecutor类来创建线程池!
- 上一篇: 后端实现Excel文件导入#阿里巴巴
- 下一篇: Java使用poi进行excel的导入操作
猜你喜欢
- 2024-11-17 「开源资讯」MyExcel 3.3.0.GA 发布,终于支持图片导入啦
- 2024-11-17 如何优雅的用POI导入Excel文件
- 2024-11-17 EasyExcel 优雅实现 Excel 导入导出
- 2024-11-17 Spring Boot框架下实现Excel服务端导入导出
- 2024-11-17 Java 设置Excel工作表的视图模式
- 2024-11-17 使用jxl将excel行转列输出
- 2024-11-17 在Java中,如何以编程的方式设置 Excel 单元格样式
- 2024-11-17 Java 将Excel工作表中的图表转换为图片
- 2024-11-17 Java 查找、替换并高亮Excel数据
- 2024-11-17 相见恨晚,用阿里 EasyExcel 优雅实现导入导出功能
你 发表评论:
欢迎- 最近发表
-
- 你真的会用 Java 中的线程池吗?多个企业级线程池工具类封装实践
- 线程池的实现原理、优点与风险、以及四种线程池实现
- Java线程池ThreadPoolExecutor实现原理剖析
- 深入分析线程池的实现原理(线程池是干嘛的)
- 一文搞懂JAVA线程池工作原理(java线程池的工作流程)
- Java线程池的工作原理(java线程池的实现原理)
- 5分钟读懂C#中TcpClient、TcpListener和Socket三个类的角色
- JVM对象的创建过程(jvm运行过程中创建的对象一般存放在方法区)
- 对象组成与Java内存模型JMM分析(java对象在内存中存储的结构)
- JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)