异步编排
@Configuration
public class MyThreadConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties pool) {
return new ThreadPoolExecutor(
pool.getCoreSize(),
pool.getMaxSize(),
pool.getKeepAliveTime(),
TimeUnit.SECONDS,
new LinkedBlockingDeque<>(100000),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
}
}
实现类中注入
@Override
public OrderConfirmVo confirmOrder() throws ExecutionException, InterruptedException {
OrderConfirmVo confirmVo = new OrderConfirmVo();
// 1.查询收获地址
// 在拦截器中获取memberId 拦截器能到达这里里面携带了id
MemberRespVo memberRespVo = LoginUserInterceptor.loginUser.get();
System.out.println("主线程..." + Thread.currentThread().getId());
CompletableFuture<Void> getAdderssFuture =
CompletableFuture.runAsync(
() -> {
System.out.println("副线程..." + Thread.currentThread().getId());
// 查询地址
List<MemberAddressVo> address = memberFeignService.getAddress(memberRespVo.getId());
confirmVo.setAddress(address);
},
executor);
CompletableFuture<Void> getCartFuture =
CompletableFuture.runAsync(
() -> {
System.out.println("副线程..." + Thread.currentThread().getId());
// 查询购物车所有选中的购物项
List<OrderItemVo> items = cartFeginService.getCurrentUserCartItems();
confirmVo.setItems(items);
},
executor);
// 查询积分
Integer integration = memberRespVo.getIntegration();
confirmVo.setIntegration(integration);
CompletableFuture.allOf(getAdderssFuture, getCartFuture).get();
return confirmVo;
}
问题
System.out.println("副线程..." + Thread.currentThread().getId());
- 控制台结果 和主线程不在一个id上 所以拦截器不会共享数据
- 原因
解决办法
- 在执行异步任务之前把
RequestContextHolder
放进去请求共享数据,每一个线程都来共享之前的数据
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
CompletableFuture<Void> getAdderssFuture =CompletableFuture.runAsync(
() -> {
System.out.println("副线程..." + Thread.currentThread().getId());
// 放入请求RequestContextHolder
RequestContextHolder.setRequestAttributes(requestAttributes);
List<MemberAddressVo> address = memberFeignService.getAddress(memberRespVo.getId());
confirmVo.setAddress(address);
},
executor);
- 重启服务之后 vo里就有数据了