多线程处理数据工具类
为减少重复代码,这里将多线程的动作使用Function接口
1、第一步定义逻辑实现
// 执行批量插入的逻辑实现
Function<List<HostPojo>, Integer> batchInsertHandler = (t) -> {
return hostDao.insertBatchUser(t);
};
2、第二步多线程动作实现
因为批量插入万条数据效率不及千条数据,因此采用拆分集合的形式操作
@Component
public class AssetsSyncUtil {
/**
* 每个线程处理数量
*/
private static int INTERVAL = 1000;
/**
* 多线程批量导入数据
* @param successDataList 总数据
* @param batchInsertHandler 批量插入数据逻辑
* @param <T>
*/
public <T> void batchInsertAssetsWithMultiThread(List<T> successDataList, Function<List<T>,Integer> batchInsertHandler) throws Exception {
// 每个线程处理数量
int interval = INTERVAL;
// 导入数据总数
int count = successDataList.size();
// list数据拆分数(线程启动数)
int splitNum = count/interval + 1;
if(count % interval == 0){
splitNum = count/interval;
}
// 创建线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(splitNum, splitNum, 0,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
CountDownLatch endLatch = new CountDownLatch(splitNum);
// 拆分successDataList并分配给每个线程
Stream.iterate(0, n -> n + 1).limit(splitNum).forEach(i -> {
List<T> collectList = successDataList.stream().skip(i * interval).limit(interval).collect(Collectors.toList());
Future<Integer> submit = threadPoolExecutor.submit(new BatchInsertExcelThread(endLatch, () -> {
// 批量插入数据
return batchInsertHandler.apply(collectList);
}));
try {
submit.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
});
// 所有数据都处理后再返回
endLatch.await();
threadPoolExecutor.shutdown();
}
}
3、第三步调用工具类
assetsSyncUtil.batchInsertAssetsWithMultiThread(collect,batchInsertHandler);