线程间共享 部分变量 Spring框架下向异步线程传递HttpServletRequest参数
参考
https://www.jianshu.com/p/6bf1adb775e0
https://blog.csdn.net/kid551/article/details/88703414
需求场景,
当前请求会话中任意位置获取到当前的请求和会话数据
以下方数据举例
HttpSession session,
HttpServletRequest request ,
HttpServletResponse response
解决方法:使用ThreadLocal 存储
定义工具类暂时存储每一个ThreadLocal
定义的时候使用了多态,当前线程的子线程,子子孙孙都可以使用,
只是用ThreadLocal 的话, 只在当前线程生效
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;public class Const {private static ThreadLocal<HttpServletRequest> requests = new InheritableThreadLocal<HttpServletRequest>();private static ThreadLocal<HttpServletResponse> responses = new InheritableThreadLocal<HttpServletResponse>();private static ThreadLocal<HttpSession> sessions = new InheritableThreadLocal<HttpSession>();public static void setSession(HttpSession value){sessions.set(value);}public static HttpSession getSession(){return sessions.get();}public static HttpServletRequest getReq(){return requests.get();}public static void setReq(HttpServletRequest value){requests.set(value);}public static void setRes(HttpServletResponse value){responses.set(value);}public static HttpServletResponse getRes(){return responses.get();}
}
有了存储工具类, 只需要在请求到来时,拦截并存储下来就好了
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("过滤器执行了。。。。。");Const.setReq((HttpServletRequest)servletRequest);Const.setRes((HttpServletResponse)servletResponse);Const.setSession(((HttpServletRequest) servletRequest).getSession());filterChain.doFilter(servletRequest,servletResponse);}
在当前线程,或是当前线程的子线程中,直接使用就好了
异步或是多线程情况下
至于网络上的其他说法
使用
// 将request设置为子线程共享ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();RequestContextHolder.setRequestAttributes(sra, true);
这部分代码类线程或是异步开始前设置,一定程度上是可行的,
一定程度指:当子线程执行完毕,主线程还存活,主线程中被传输的参数映射还没有被销毁的时候。
当主线程执行完毕,子线程却刚刚开启,主线程中的request对象可能已经被干掉了,子线程中获取seesion为null 只对于session
测试部分
@RequestMapping("/testSession1")public void testSession1(HttpServletRequest request , HttpServletResponse response)throws Exception{testSession("普通调用",request.getSession(),request,response);}@RequestMapping("/testSession2")public void testSession2(HttpServletRequest request , HttpServletResponse response)throws Exception{new Thread(() -> {testSession("线程调用",request.getSession(),request,response);}).start();}@RequestMapping("/testSession3")public void testSession3(HttpServletRequest request , HttpServletResponse response)throws Exception{CompletableFuture.runAsync(() -> {testSession("异步调用",request.getSession(),request,response);});}@RequestMapping("/testSession4")public void testSession4(HttpServletRequest request , HttpServletResponse response)throws Exception{new Thread(() -> {testSession("线程调用",Const.getSession(),request,response);}).start();}@RequestMapping("/testSession5")public void testSession5(HttpServletRequest request , HttpServletResponse response)throws Exception{CompletableFuture.runAsync(() -> {testSession("异步调用",Const.getSession(),request,response);});}private void testSession(String str , HttpSession session,HttpServletRequest request , HttpServletResponse response){try {Thread.sleep(4000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("-------"+str+"-------");System.out.println(session);System.out.println(request);System.out.println(response);System.out.println("-------"+str+"-------");}
线程间共享 部分变量 Spring框架下向异步线程传递HttpServletRequest参数相关推荐
- Disruptor 线程间共享数据无需竞争
队列的作用是缓冲 缓冲到 队列的空间里.. 线程间共享数据无需竞争 原文 地址 作者 Trisha 译者:李同杰 LMAX Disruptor 是一个开源的并发框架,并获得2011 Duke' ...
- 深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议
前言 消息队列在现今数据量超大,并发量超高的系统中是十分常用的.本文将会对现时最常用到的几款消息队列框架 ActiveMQ.RabbitMQ.Kafka 进行分析对比. 详细介绍 RabbitMQ 在 ...
- C++并发编程线程间共享数据std::future和sd::promise
线程间共享数据 使用互斥锁实现线程间共享数据 为了避免死锁可以考虑std::lock()或者boost::shared_mutex 要尽量保护更少的数据 同步并发操作 C++标准库提供了一些工具 可以 ...
- Linux系统编程---13(线程控制函数,创建线程,循环创建多个线程,线程间共享全局变量)
线程控制 操作系统并没有提供创建线程的系统调用接口,因此大佬们封装了一个线程的接口库实现线程控制.意为着用户创建线程都使用的是库函数(所以有时候我们说创建的线程是一个用户态线程,但是在内核中对应有一个 ...
- java 多线程共享变量两类问题_Java并发基础09. 多个线程间共享数据问题
先看一个多线程间共享数据的问题: 设计四个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显涉及到了线程间通数据的共享,四个线程共享一个 data,共同操作 ...
- java 多个线程共享数据_【java并发】多个线程间共享数据
先看1个多线程间同享数据的问题: 设计4个线程,其中两个线程每次对data增加1,另外两个线程每次对data减少1. 从问题来看,很明显触及到了线程间通数据的同享,4个线程同享1个data,共同操作1 ...
- C++线程间共享数据
通常我们使用锁保护线程间共享数据,这也是最基本的方式. 当访问共享数据前,使用互斥量将相关数据锁住,再当访问结束后,再将数据解锁.线程库需要保证,当一个线程使用特定互斥量锁住共享数据时,其他的线程想要 ...
- java 自动装载_java_详解Java的Spring框架下bean的自动装载方式,Spring容器可以自动装配相互协 - phpStudy...
详解Java的Spring框架下bean的自动装载方式 Spring容器可以自动装配相互协作bean之间的关系,这有助于减少对XML配置,而无需编写一个大的基于Spring应用程序的较多的和元素. 自 ...
- 解决Spring框架下中文乱码的问题
解决Spring框架下中文乱码的问题 参考文章: (1)解决Spring框架下中文乱码的问题 (2)https://www.cnblogs.com/Summer7C/p/4712818.html (3 ...
最新文章
- eclipse 配置java路径_Java修改eclipse中web项目的server部署路径问题
- C/C++指针函数和函数指针
- Teradata大数据新动作:通过统一数据架构拥抱开源
- 自己构建GlassFish 4.0快照
- 超级*** 08鬼斧神工
- 《移动通信》学习总结
- Chrome浏览器导出插件crx
- mysql数据库详细设计实例_MYSQL数据库设计和数据库设计实例(二)
- Android 8.0 新特性(一) - 可下载字体
- 【机器学习】【决策树】自己动手用Python实现一个类:in样本集,out特征分布、概率密度、熵、条件熵、信息增益、信息增益比
- pytorch Bus error (core dumped)
- A Framework for Multi-stage Bonus Allocation in meal delivery Platform
- 大写字母转小写(及scanf中的间隔符号的影响)
- python3.8与pyinstaller_pyinstaller 3.5 在python 3.8 环境下出现不兼容的问题
- Vue响应式原理(看这一篇就够了)
- 统计学 分布篇 - Binomial Distribution(二项分布)
- 成熟的人不问过去,聪明的人不问现在,豁达的人不问未来~!
- 70 告别了,2013-2021【2021-06-05 1854】
- 大数据原生集群本地测试环境搭建三
- 我们年轻时,为什么要辛苦赚钱,这是我听过的最好回答!
热门文章
- Papi酱: 左手奶瓶右手尿布× 左手papitube右手娱乐圈√
- 【shell】How can I create a select menu in a shell script?
- 根据从数据库中获取到的值控制按钮被选中
- 在线五子棋对战 --- 人机对战的实现
- R语言中的函数5:purrr:map()
- C22_OC12-protocol协议
- [x y w h]转化为[ymin xmin ymax xmax]
- matlab rgb三维直方图,MATLAB小技巧之十:利用MATLAB绘制三维彩色柱状图[转载]
- 一文掌握多分类logistic回归
- javascript代码规范及格式化工具