多线程异步
在使用多线程时,由于线程的执行是异步的,我们在线程启动后就无法得知线程的执行结果,甚至连执行到哪里都是未知的,比如下面的代码
for (int i = 0; i < 6; i++) {
int finalI = i + 1;
executor.submit(() -> {
System.out.println("Execute Thread start: " + finalI);
});
System.out.println("Execute Thread end: " + (i + 1) + "----------------------");
}
System.out.println("Execute Threads All End.");
执行结果可能是
Execute Thread end: 1----------------------
Execute Thread end: 2----------------------
Execute Thread end: 3----------------------
Execute Thread end: 4----------------------
Execute Thread end: 5----------------------
Execute Thread end: 6----------------------
Execute Threads All End.
Execute Thread start: 1
Execute Thread start: 3
Execute Thread start: 4
Execute Thread start: 2
Execute Thread start: 6
Execute Thread start: 5
也有可能是
Execute Thread end: 1----------------------
Execute Thread end: 2----------------------
Execute Thread start: 1
Execute Thread end: 3----------------------
Execute Thread start: 3
Execute Thread start: 2
Execute Thread start: 4
Execute Thread end: 4----------------------
Execute Thread end: 5----------------------
Execute Thread start: 5
Execute Thread end: 6----------------------
Execute Threads All End.
Execute Thread start: 6
如果我们现在的需求是要在所有线程执行完后再进行某些操作,比如调用接口查找一些用户的数据,组装成一组数据集后插入数据库,就必须要等到所有线程执行完后再批量插入,要怎么做呢?
较为常用的做法就是使用CompletableFuture
CompletableFuture
简单来说,CompletableFuture是Java1.8以后提供的并发控制类,可以自动阻塞直到获取任务执行的结果
CompletableFuture<String> future = CompletableFuture.supplyAsync(()->{
String result = null;
// 任务执行
return result;
});
// 会一直阻塞直到获取到执行结果
future.get();
多线程并发阻塞等待所有线程执行完毕
通过CompletableFuture,我们就可以实现多线程的阻塞,只需要把所有的线程执行结果都放到一个CompletableFuture的集合中,然后获取结果即可
最终代码
List<CompletableFuture> futureList = new ArrayList<>();
for (UserEntity entity: userEntities) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
// 业务逻辑
});
futureList.add(future);
}
// 使用列表和数组的方式获取所有future, 实现阻塞
CompletableFuture[] futureArray = new CompletableFuture[futureList.size()];
futureList.toArray(futureArray);
CompletableFuture.allOf(futureArray).join();
//也可以简写为CompletableFuture.allOf(futureList.toArray(new CompletableFuture[0])).join();