原因:
最近写项目多时候遇到一个这样的问题,Excel批量导入表格,数据量较大,处理时间较长。然后小编想到了可以用多线程处理。
例:
//导入失败集合
List<BatchPayDetailExcelDto> batchPayDetailExcelVoFailList = new CopyOnWriteArrayList<>();
//导入成功集合
List<BatchPayDetailExcelDto> batchPayDetailExcelVoSuccessList = new CopyOnWriteArrayList<>();
int totalSize = batchPayDetailList.size(); //总数量
final int[] currentNum = {0}; //当前处理数量
/******************************************多线程处理开始*****************************************/
// 一百条为基准为一个线程处理
List<List<BatchPayDetailExcelDto>> groupList = CommonUtils.partition(batchPayDetailList, 100);
CountDownLatch countDownLatch = new CountDownLatch(groupList.size());
ExecutorService executorService = Executors.newFixedThreadPool(groupList.size());
for (int i = 0; i < groupList.size(); i++) {
int finalI = i;
executorService.execute(() -> {
List<BatchPayDetailExcelDto> batchPayDetailGroup = groupList.get(finalI);
for (BatchPayDetailExcelDto batchPayDetailExcel : batchPayDetailGroup) {
currentNum[0]++;
//创建业务消息信息 -- 导入进度
JSONObject obj = new JSONObject();
obj.put("cmd", MyConstants.PREFIX_CMD_PAY);//业务类型
obj.put("msgId", merchantId);//消息id
obj.put("msgTxt", CommonUtils.proportionInt(currentNum[0], totalSize).replace("%", ""));//当前导入进度
// //单个用户发送 (userId为用户id)
webSocket.sendOneMessage(sysUser.getId(), obj.toJSONString());
String name = batchPayDetailExcel.getName();
String idCard = batchPayDetailExcel.getIdCard();
double money = batchPayDetailExcel.getFee();
if (!ValidUtil.validName(name.trim())) {
batchPayDetailExcel.setRemark("名字校验失败!");
batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
continue;
}
if (!ValidUtil.validIdCardNo(idCard.trim())) {
batchPayDetailExcel.setRemark("身份证号校验失败!");
batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
continue;
}
if (!ValidUtil.isNumber(money + "")) {
batchPayDetailExcel.setRemark("金额校验失败,仅支持精确到两位小数!");
batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
continue;
}
if (money < 10) {
batchPayDetailExcel.setRemark("单笔代发交易金额不能低于10元!");
batchPayDetailExcelVoFailList.add(batchPayDetailExcel);
continue;
}
batchPayDetailExcelVoSuccessList.add(batchPayDetailExcel);
}
countDownLatch.countDown();
});
}
countDownLatch.await();
executorService.shutdown(); //关闭线程池
注意:集合线程同步使用CopyOnWriteArrayList
工具类
/**
* 集合按长度分组
*
* @param list
* @param size
* @param <T>
* @return
*/
public static <T> List<List<T>> partition(final List<T> list, final int size) {
if (list == null) {
throw new IllegalArgumentException("List must not be null");
}
if (size <= 0) {
throw new IllegalArgumentException("Size must be greater than 0");
}
List<List<T>> result = new ArrayList<>();
Iterator<T> it = list.iterator();
List<T> subList = null;
while (it.hasNext()) {
if (subList == null) {
subList = new ArrayList<>();
}
T t = it.next();
subList.add(t);
if (subList.size() == size) {
result.add(subList);
subList = null;
}
}
//补充最后一页
if (subList != null) {
result.add(subList);
}
return result;
}