项目背景
在实际开发过程中,需要循环从第三方接口获取医生排班数据,如果是单线程在调用,一次200ms,一组排班就20个医生,就需要20*200ms=4s。所以选择多线程异步请求方案。
由于懒得写demo,直接把代码(进行了删减,关键信息已剔除)贴上来了,不能直接用,打开看个思路
线程池
先开一个线程池,写一个异步线程,返回类型Future<>
/**
* @Author liuyg
* @Description 异步查询排班
* @Date 2022/5/13 16:48
* @Param notifyCountInfo
*/
@Async("myExecutor")
public Future<List<QueryDeptScheduleDto>> latestNucleicAcidTestReport(QueryDeptDoctorVo par,QueryDeptDoctorDto queryDeptDoctorDto) {
ReturnVO returnVO = hisService.deptScheduleList(queryDeptDoctorDto);
List<QueryDeptScheduleDto> queryDeptScheduleDtos = (List<QueryDeptScheduleDto>) returnVO.getData();
queryDeptDoctorDto.setDeptScheduleList(queryDeptScheduleDtos);
return new AsyncResult<>(queryDeptScheduleDtos);
}
在service类中调用
List<Future<List<QueryDeptScheduleDto>>> futures = new ArrayList<>();
for (int i = 0; i < doctorList.size(); i++) {
//异步查询排班
Future<List<QueryDeptScheduleDto>> queryDeptScheduleDto = hisAsyncTaskExecute.latestNucleicAcidTestReport(par, queryDeptDoctorDto);
futures.add(queryDeptScheduleDto);
}
在循环等待返回值就可以了,这里需要执行sleep进行睡眠,不然会一直循环对cpu压力很大
//查询任务执行的结果
while (true) {
boolean flag = false;
for (int i = 0; i < futures.size(); i++) {
Future<List<QueryDeptScheduleDto>> listFuture = futures.get(i);
if (listFuture.isDone()) {
flag = true;
} else {
flag = false;
try {
Thread.sleep(30);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
break;
}
}
if (flag) {
break;
}
}
效果展示
接口请求耗时367ms。其中请求了10次第三方接口,每次请求在160ms左右。
160ms*10=1.6s ,实际耗费367ms,速度快了5倍左右。
注意
如果使用此方法,要注意
第三方接口是否顶得住并发压力
你的程序调用次数是多少,如果是上万次调用启用上万个线程,恐怕自己服务器也吃不消
评论区