需求
上千万数据,分批处理,数据组装后插入到MySQL当中。
痛病
插入效率(耗时极其长)
如何集合分段:
方式1
方式二
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
//拆分结合API
List<List<Integer>> partition = Lists.partition(list, 10);
需求的解决方案与思路
public class MyCountDownLatch {
public static final String SONG="---宋先阳";
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 初始化线程池
ExecutorService threadPool = Executors.newFixedThreadPool(20);
List<Integer> list = new ArrayList<>();
// 往集合中添加数据
IntStream.rangeClosed(0,20).forEach(list::add);
// 集合分段
List<List<Integer>> lists = SplitListUtils.split(list, 10);
// 记录单个任务的执行次数
CountDownLatch downLatch = new CountDownLatch(lists.size());
// 新增数据的list
List<String> insertList = Lists.newArrayList();
for (List<Integer> integerList : lists) {
// 有返回值的API
CompletableFuture<List<String>> listCompletableFuture = CompletableFuture.supplyAsync(() ->
// 封装处理返回值的方法
getStrings(integerList),
// 自定义的线程池
threadPool
);
// 获取线程中结果放入:新增数据的list
insertList.addAll(listCompletableFuture.get());
// 任务个数 - 1, 直至为0时唤醒await()
downLatch.countDown();
System.out.println("个数::::"+downLatch.getCount());
}
// 让当前线程处于阻塞状态,直到锁存器计数为零
downLatch.await();
// 批量新增
if (!CollectionUtils.isEmpty(insertList)) {
// 执行DAO中的批量新增:
System.out.println(insertList);
}
}
private static List<String> getStrings(List<Integer> integerList) {
List<String> childList = Lists.newArrayList();
for (Integer integer : integerList) {
String s=integer+SONG;
childList.add(s);
}
return childList;
}
}
学习 CountDownLatch、CompletableFuture 搭配使用:MyCountDownLatch