场景
读取一个Excel表格,对Excel表格中的数据进行某个算法处理,但是这个算法会耗费大量的时间,此时单线程处理效率极慢。
处理方式
1.常规单线程处理,在数据量小且执行速度快的情况下可以直接使用
List<PointModel> excelData = ExcelUtils.getExcelData(file.getInputStream(), PointModel.class);
for (PointModel excelDatum : excelData) {
doSomething(excelDatum);
}
2.多线程处理,为了避免同一数据重复消费,需使用subList,可参考
https://www.cnblogs.com/-lpf/p/4633673.html
3.在上述方法上进行扩展,如果每个人物都写一个线程类,在一定程度上会造成代码的冗余并且修改比较麻烦,而jdk1.8之后的函数式编程恰恰可以解决这个问题。
2021-11-26
本文记录较早,下面两种方式实现会更简单好用,推荐stream
1.使用Lists.partition()拆分后线程池执行
2.使用parral stream直接foreach
使用Consumer多线程消费优化
1.新建一个MultiThreadHandle类
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
/**
* Created on 2020/2/27.
* 多线程处理List
*
* @author cjd
*/
public class MultiThreadHandle<T> {
private ExecutorService executorService = Executors.newCachedThreadPool();
public MultiThreadHandle(List<T> sumList, int threadNum, Consumer<List<T>> consumer) {
int length = sumList.size();
// 线程处理数量
int dealNum = length % threadNum == 0 ? length / threadNum : (length
/ threadNum + 1);
for (int i = 0; i < threadNum; i++) {
int start = i * dealNum;
int end = (i + 1) * dealNum;
List<T> tempData = sumList.subList(start, Math.min(end, length));
executorService.execute(() -> {
consumer.accept(tempData);
});
}
}
}
2.将算法doSomeThing注入即可实现多线程消费,搭配使用CountDownLatch来保证所有线程任务执行结束。
int threadNum = 16;
if (excelData.size() > threadNum) {
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
new MultiThreadHandle<>(excelData, threadNum, (list) -> {
for (GeoHashViewModel geoHashViewModel : list) {
doSomeThing(list);
}
countDownLatch.countDown();
});
countDownLatch.await();
}