一、用线程池的时候用Future来接收实现了Callable的线程实现类的返回值,应用如下
/**
* 下单线程实现类
*/
class OrderCallable implements Callable<List<OrderInfo>> {
private List<OrderInfo> orderInfos;
private UserDTO user;
OrderCallable(List<OrderInfo> orderInfos, UserDTO user) {
this.orderInfos = orderInfos;
this.user = user;
}
@Override
public List<OrderInfo> call() {
List<OrderInfo> rs = new ArrayList<>();
for (OrderInfo orderInfo : orderInfos) {
logger.info("开始下单:{}", orderInfo.getOrderId());
orderInfo = orderDifferentService(orderInfo, user);
rs.add(orderInfo);
logger.info("下单返回:{}, {}", orderInfo.getOrderId(), orderInfo.getOrderState());
}
return rs;
}
}
二、线程池调用
/**
* 后台批量下单才启用线程池,接口无须开启
*/
private List<OrderInfo> syncOrderWithThreadPool(List<OrderInfo> orderInfos, UserDTO user) {
List<List<OrderInfo>> orderLists = Lists.partition(orderInfos, 50);
List<OrderInfo> rsList = CollUtil.newArrayList();
orderLists.stream().forEach(orderList -> {
Future<List<OrderInfo>> futureRs = executorService.submit(new OrderCallable(orderList, user));
try {
List<OrderInfo> getList = futureRs.get();
rsList.addAll(getList);
} catch (Exception e) {
logger.error("future get is Error: {}", e);
}
});
return rsList;
}
三、get()方法可以当任务结束后返回一个结果,如果调用时,工作还没有结束,则会阻塞线程,直到任务执行完毕,因此看似开启了多线程,实际上还是在循环的时候进行了阻塞,和串行的效率是一样的
四、改动,使用Jdk1.8 Future的新实现类 CompletableFuture,有合并方法,也可以通过线程池初始化并通过继承Supplier获取返回值,改动如下
/**
* 下单线程实现类
*/
class OrderCallable implements Supplier<List<OrderInfo>> {
private List<OrderInfo> orderInfos;
private UserDTO user;
OrderCallable(List<OrderInfo> orderInfos, UserDTO user) {
this.orderInfos = orderInfos;
this.user = user;
}
@Override
public List<OrderInfo> get() {
List<OrderInfo> rs = new ArrayList<>();
for (OrderInfo orderInfo : orderInfos) {
logger.info("开始下单:{}", orderInfo.getOrderId());
orderInfo = orderDifferentService(orderInfo, user);
rs.add(orderInfo);
logger.info("下单返回:{}, {}", orderInfo.getOrderId(), orderInfo.getOrderState());
}
return rs;
}
}
调用
/**
* 后台批量下单才启用线程池,接口无须开启
*/
private List<OrderInfo> syncOrderWithThreadPool(List<OrderInfo> orderInfos, UserDTO user) {
List<List<OrderInfo>> orderLists = Lists.partition(orderInfos, 100);
List<OrderInfo> rsList = CollUtil.newArrayList();
List<CompletableFuture<List<OrderInfo>>> futures = new ArrayList<>();
orderLists.forEach(orderInfoModelList ->
futures.add(CompletableFuture.supplyAsync(new OrderCallable(orderInfoModelList, user),
executorService)));
// 合并
CompletableFuture<Void> all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
// 阻塞,直到所有的任务执行结束(等待最长的任务)
all.join();
try {
for (CompletableFuture future : futures) {
List<OrderInfo> getList = (List<OrderInfo>) future.get();
rsList.addAll(getList);
}
} catch (Exception e) {
logger.error("获取future返回值异常1", e);
}
return rsList;
}
五、使用CompletableFuture 的静态方法 allOf、anyOf可以根据需求合并想要的多线程结果,做到真正的并发。