1,需求场景
后台数据处理需要多个远程调用,数据拉取推送等IO操作很耗时或者时间预估困难,手动重新推送或拉取数据等操作。
2,第一种方案
直接在controller创建子线程
@RestController
@RequestMapping("/pulldata")
@Slf4j
public class PullOrderController {
@Autowired
private TestService testService;
/**
* 定义任务线程池,手动处理的情况比较少,不需要太多线程数
*/
private static ExecutorService threadPool = new ThreadPoolExecutor(1, 5, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
/**
* 拉取调拨单
*
* @param sapRequestPO
* @return
*/
@PostMapping(value = "test")
public Result list(@RequestBody SapRequestPO sapRequestPO) {
log.debug("主线程开始");
Callable<Boolean> callable = new Callable<Boolean>() {
@Override
public Boolean call(){
log.debug("子线程开始");
boolean res = testService.pullStockOutOrderByQm(
sapRequestPO.getFromWho(),
sapRequestPO.getShopno(),
sapRequestPO.getSaledate(),
sapRequestPO.getOrderno());
log.debug("子线程结束");
return res;
}
};
threadPool.submit(callable);
log.debug("主线程结束");
return Result.success();
}
}
2,第二种方案
耗时任务实现 Runnable
@Slf4j
@Service
@AllArgsConstructor
public class IotService implements Runnable{
private final HwApicService hwApicService;
private final ApoiSbxxDao apoiSbxxDao;
/**
* 同步物联设备到数据库
*/
@SneakyThrows
@Override
public void run() {
// //当前偏移量
// int offset = 0;
// //当前页返回行数
// int resDataSize = 0;
// String gxsjStr = DateUtil.formatDateTime(new Date());
// //循环同步物联设备
// do {
// resDataSize = extracted(gxsjStr, offset);
// offset = offset + 1000;
// }
// while (resDataSize == 1000);
// log.warn("同步完成,offset:{}",offset);
// apoiSbxxDao.del("iot", gxsjStr);
//模拟耗时任务执行60秒
System.out.println("任务执行开始");
Thread.sleep(60000);
System.out.println("任务执行结束");
}
}
@Api(tags = "测试")
@RequestMapping("/tup")
@RestController
public class TupController {
private final IotService wlService;
public TupController(IotService wlService) {
this.wlService = wlService;
}
@GetMapping("/syncget")
@ApiOperation(value = "测试异步请求")
public Rest<String> test1() throws Exception {
//不需要返回值
CompletableFuture.runAsync(wlService);
return Rest.success(DateUtil.now());
}
}