需求: 做数据统计,但是有的sql执行太慢。然后优化添加索引,再用线程池去执行各自sql。汇总结果集
需要注意下:每次异步执行需要创建一个新对象,不要复用对象。get()得方法就有阻塞等待线程处理完成得效果。做到最后数据都能拿到。
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
/**
* @author xyd
* @description:
* @date 2020/3/23
*/
public class demo {
/**
* 获取基本信息
*
* @return
*/
public static String getProductBaseInfo(String productId) {
return productId + "商品基础信息";
}
/**
* 获取详情信息
*
* @return
*/
public static String getProductDetailInfo(String productId) throws InterruptedException {
Thread.sleep(20000L);
return productId + "商品详情信息";
}
/**
* 获取sku信息
*
* @return
*/
public static String getProductSkuInfo(String productId) throws InterruptedException {
Thread.sleep(10000L);
return productId + "商品sku信息";
}
/**
* 取得一个商品的所有信息(基础、详情、sku)
*
* @param productId
* @return
*/
public static String getAllInfoByProductId(String productId) {
ExecutorService executor = Executors.newFixedThreadPool(10);
CompletableFuture<String> f1 = CompletableFuture.supplyAsync(() -> getProductBaseInfo(productId), executor);
CompletableFuture<String> f2 = CompletableFuture.supplyAsync(() -> {
try {
return getProductDetailInfo(productId);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}, executor);
CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
try {
return getProductSkuInfo(productId);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}, executor);
try {
String baseInfo = f1.get();
String detailInfo = f2.get();
String skuInfo = f3.get();
return baseInfo + "" + detailInfo + skuInfo;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
System.out.println(getAllInfoByProductId("xyd"));
}
}
runAsync 没有返回值
supplyAsync 需要返回值
多线程异步求同一个接口时。
private static void batchGenTableRecord(JudgeComponentFetchLogicBO logic, Map<String, Object> baseInfo,
Map<String, Object> extraInfo, Map<String, Object> dataSourceValue, List<Integer> indexList,
Map<Integer, List<ComponentViewRecordBO>> vMap, Map<String, List<Map>> sourceMap) {
CompletableFuture<Void> all = CompletableFuture.allOf(
indexList.stream().map(index -> CompletableFuture.supplyAsync(() -> {
genTableRecord(logic, baseInfo, extraInfo, dataSourceValue, index, vMap, sourceMap);
return vMap;
}, ThreadPoolUtil.COMPONENT_POOL).exceptionally(e -> {
log.error("asyncGenTableComponentData error: {}", e.getMessage());
return vMap;
})).toArray(CompletableFuture[]::new));
//阻塞,直到所有任务结束。
all.join();
}
public QueueGatherResultBO queryJudgeQueueGatherListByStaff(String staff) {
if (StringUtils.isBlank(staff)) {
throw JudgeException.of(ErrorCode.PARAM_INVALID);
}
QueueGatherResultBO result = new QueueGatherResultBO();
//1.获取用户绑定的队列集
List<Long> gatherIds = orgStructureService.queryGatherListByStaff(staff);
log.info("queryJudgeQueueGatherListByStaff.queryGatherListByStaff.result:{}",
JsonMapperUtils.toJson(gatherIds));
if (CollectionUtils.isEmpty(gatherIds)) {
return result;
}
//2。查询每个队列集详情信息
//队列集信息获取(队列id对应队列的名称,kconf维护的)
List<QueueGatherConf> resList = ThemisJudgeJsonListConfigKey.queueGatherList.getList();
Map<Long, String> queueGatherMap =
resList.stream().collect(Collectors.toMap(QueueGatherConf::getId, QueueGatherConf::getName));
CopyOnWriteArrayList<QueueGatherBO> queueGatherList = new CopyOnWriteArrayList<>();
CopyOnWriteArrayList<GatherQueueListBO> queueGatherAllList = new CopyOnWriteArrayList<>();
//多线程查询每个队列集下,队列列表信息(队列集绑定队列)
CompletableFuture<Void> all = CompletableFuture.allOf(
gatherIds.stream().map(n -> CompletableFuture.runAsync(() -> {
List<GatherQueueListBO> queueList = this.queryJudgeQueueListByGatherId(staff, n);
log.info("queryJudgeQueueGatherListByStaff.queryJudgeQueueListByGatherId.result:{}",
JsonMapperUtils.toJson(queueList));
if (!CollectionUtils.isEmpty(queueList)) {
//聚合待审核数量
int waitNumber = queueList.stream().mapToInt(GatherQueueListBO::getWaitNumber).sum();
//聚合已进审数量
int reviceeNumber = queueList.stream().mapToInt(GatherQueueListBO::getReviewedNumber).sum();
QueueGatherBO build =
QueueGatherBO.builder().gatherId(Math.toIntExact(n)).gatherName(queueGatherMap.get(n))
.reviewedNumber(reviceeNumber)
.waitNumber(waitNumber).build();
queueGatherList.add(build);
queueGatherAllList.addAll(queueList);
}
}, ThreadPoolUtil.COMPONENT_POOL).exceptionally(e -> {
log.error("asyncGenTableComponentData error: {}", e.getMessage());
throw JudgeException.of(ErrorCode.SYSTEM_ERROR.getCode(), "获取队列集数据失败");
//不用异常 就return null;
})).toArray(CompletableFuture[]::new));
//阻塞,直到所有任务结束。
all.join();
//3。封装结果
List<GatherQueueListBO> collect = queueGatherAllList.stream().distinct().collect(Collectors.toList());
int reviewedSum = collect.stream().mapToInt(GatherQueueListBO::getReviewedNumber).sum();
int waitSum = collect.stream().mapToInt(GatherQueueListBO::getWaitNumber).sum();
QueueGatherBO allData =
QueueGatherBO.builder().reviewedNumber(reviewedSum).waitNumber(waitSum).gatherId(0).gatherName("全部")
.build();
result.setQueueGatherList(queueGatherList);
result.setQueueGatherAll(allData);
return result;
}
并行执行调用做数据聚合