跳到主要内容

多线程调用服务情况下解决数据丢失

在上一章节讲解了在服务调用的过程中,由于flux是异步调用,所以线程发生了变化,解决ThreadLocal在此情况下的数据传递问题。 但还并没有完,关于多线程还有其他的问题,用案例来模拟下

案例

@RequestMapping(value = "/call/async")
public Map<String,Map<String,String>> callAsync(){
Map<String,Map<String,String>> resultMap = new HashMap<>(2);
Map<String, String> consumerServiceMap = metaDataOperation.getInfo();
resultMap.put("consumer-service",consumerServiceMap);
threadPoolExecutor.execute(() -> {
System.out.println("线程池调用线程:"+Thread.currentThread().getName());
Map<String, String> providerServiceMap = providerClient.call();
resultMap.put("provider-service",providerServiceMap);
});
return resultMap;
}

在线程池中调用了 provider-service,执行过程会发现,从请求头中获取数据时,从 BaseParameterHolder 中获取 ServletRequestAttributes 为空,我把这部分代码贴出来

public String getValueFromHeader(String name) {
//先获取到HttpServletRequest,然后再获取到请求头的值
HttpServletRequest request = getHttpServletRequest();
if (request != null) {
return request.getHeader(name);
}
return null;
}

public HttpServletRequest getHttpServletRequest() {
//先从线程上下文中获取HttpServletRequest,如果没有再从ServletRequestAttributes中获取
ServletRequestAttributes attributes = null;
Object parameter = BaseParameterHolder.getParameter(WorkConstant.REQUEST_ATTRIBUTES);
if (Objects.nonNull(parameter)) {
attributes = (ServletRequestAttributes) parameter;
}
if (attributes == null) {
attributes = getRequestAttributes();
}
if (attributes == null) {
return null;
}
return attributes.getRequest();
}

public ServletRequestAttributes getRequestAttributes() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return null;
}
return (ServletRequestAttributes) requestAttributes;
}

有人看了可能会有个疑问,代码中先从 BaseParameterHolder 中获取,下面不还是有个从 RequestContextHolder 再获取吗,不好意思 RequestContextHolder 是Spring提供的,它也是 ThreadLocal 结构。这个只是为了代码健壮性,取其他数据的作用。

那这要怎么处理?先把上一章节提到的线程切换过程再看一下

付费内容提示

该文档的全部内容仅对「JavaUp项目实战&技术讲解」知识星球用户开放

加入星球后,你可以获得:

  • 超级八股文:100万+字的全栈技术知识库,涵盖技术核心、数据库、中间件、分布式等深度剖析的讲解
  • 讲解文档:黑马点评Plus、大麦、大麦pro、大麦AI、流量切换、数据中台的从0到1的550+详细文档
  • 讲解视频:黑马点评Plus、大麦、大麦pro、大麦AI、流量切换、数据中台的核心业务详细讲解
  • 1 对 1 解答:可以对我进行1对1的问题提问,而不仅仅只限于项目
  • 针对性服务:有没理解的地方,文档或者视频还没有讲到可以提出,本人会补充
  • 面试与简历指导:提供面试回答技巧,项目怎样写才能在简历中具有独特的亮点
  • 中间件环境:对于项目中需要使用的中间件,可直接替换成我提供的云环境
  • 面试后复盘:小伙伴去面试后,如果哪里被面试官问住了,可以再找我解答
  • 远程的解决:如果在启动项目遇到问题,本人可以帮你远程解决
进入星球后,即可享受上述所有服务,保证不会再有其他隐藏费用。
知识星球二维码

1. 打开微信 -> 扫描左侧二维码 -> 加入「JavaUp项目实战&技术讲解」知识星球

2. 查看星球使用指导,获取完整项目讲解资料索引

👉 点击解锁全部付费内容
🎁优惠