关于java并发场景下,HttpServletRequst中session丢失问题
使用场景:
在list数据进来之后使用安全数组 Lists.newCopyOnWriteArrayList()
进行了 parallelStream 并行处理,在接口中进行了登录者信息接口的调用,获取方式是从当前登录的requst中获取用户携带的session信息,在并行处理的过程中出现调用NPE异常信息。
问题排查:
public static ServletRequestAttributes getRequestAttributes() {
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return (ServletRequestAttributes)attributes;
}
上述方法中 RequestContextHolder.getRequestAttributes(); 获取到的是NULL对象,来源于
@Nullable
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = (RequestAttributes)requestAttributesHolder.get();
if (attributes == null) {
attributes = (RequestAttributes)inheritableRequestAttributesHolder.get();
}
return attributes;
}
上述方法中获取方式:
(RequestAttributes)requestAttributesHolder.get();或者
RequestAttributes)inheritableRequestAttributesHolder.get();
出现了null空值,原因是子线程获取了当前线程组中的参数为空:
private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");
private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");
具体的实现是:

public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
执行了最后的
setInitialValue();方法,此方法中返回了null;传递至其调用方法造成的NPE异常;
原因
主线程中request对象在创建子线程并行执行的时候没有将request对象共享给子线程,导致的null空指针,具体原因可参考request和response设置的底层实现;
/**
* Bind the given RequestAttributes to the current thread.
* @param attributes the RequestAttributes to expose,
* or {@code null} to reset the thread-bound context
* @param inheritable whether to expose the RequestAttributes as inheritable
* for child threads (using an {@link InheritableThreadLocal})
*/
public static void setRequestAttributes(@Nullable RequestAttributes attributes, boolean inheritable) {
if (attributes == null) {
resetRequestAttributes();
}
else {
if (inheritable) {
inheritableRequestAttributesHolder.set(attributes);
requestAttributesHolder.remove();
}
else {
requestAttributesHolder.set(attributes);
inheritableRequestAttributesHolder.remove();
}
}
}
/**
* Return the RequestAttributes currently bound to the thread.
* @return the RequestAttributes currently bound to the thread,
* or {@code null} if none bound
*/
@Nullable
public static RequestAttributes getRequestAttributes() {
RequestAttributes attributes = requestAttributesHolder.get();
if (attributes == null) {
attributes = inheritableRequestAttributesHolder.get();
}
return attributes;
}
解决办法
1.监听所有的请求,以监听器处理;初始化的时候添加请求监听器;
/**
* 监听器:监听HTTP请求事件
* 解决RequestContextHolder.getRequestAttributes()空指针问题
* @return
*/
@Bean
public RequestContextListener requestContextListener(){
return new RequestContextListener();
}
2.将当前线程的变量共享给子线程;并行请求开始的前先做变量共享。
ServletRequestAttributes servletRequst= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
RequestContextHolder.setRequestAttributes(servletRequst,true);
关于java并发场景下,HttpServletRequst中session丢失问题的更多相关文章
- Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%。再往后,每提高0.1%,优化难度成指数级增长了。哪怕是千分之一,也直接影响用户体验,影响每天上万张机票的销售额。 在高并发场景下,提供了保证线程安全的对象、方法。比如经典的ConcurrentHashMap,它比起HashMap,有更小粒度的锁,并发读写性能更好。线程安全的StringBuilder取代S
Qunar机票技术部就有一个全年很关键的一个指标:搜索缓存命中率,当时已经做到了>99.7%.再往后,每提高0.1%,优化难度成指数级增长了.哪怕是千分之一,也直接影响用户体验,影响每天上万张机 ...
- HashMap在并发场景下踩过的坑
本文来自网易云社区 作者:张伟 关于HashMap在并发场景下的问题有很多人,很多公司遇到过!也很多人总结过,我们很多时候都认为这样都坑距离自己很远,自己一定不会掉入这样都坑.可是我们随时都有就遇到了 ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化 以及SnowFlakeIdWorker高性能ID生成器
package xxx; import java.sql.Timestamp; import java.util.concurrent.*; import java.util.concurrent.a ...
- 【转】记录PHP、MySQL在高并发场景下产生的一次事故
看了一篇网友日志,感觉工作中值得借鉴,原文如下: 事故描述 在一次项目中,上线了一新功能之后,陆陆续续的有客服向我们反应,有用户的个别道具数量高达42亿,但是当时一直没有到证据表示这是,确实存在,并且 ...
- HttpClient在高并发场景下的优化实战
在项目中使用HttpClient可能是很普遍,尤其在当下微服务大火形势下,如果服务之间是http调用就少不了跟http客户端找交道.由于项目用户规模不同以及应用场景不同,很多时候可能不需要特别处理也. ...
- 高并发场景下System.currentTimeMillis()的性能问题的优化
高并发场景下System.currentTimeMillis()的性能问题的优化 package cn.ucaner.alpaca.common.util.key; import java.sql.T ...
- C++高并发场景下读多写少的解决方案
C++高并发场景下读多写少的解决方案 概述 一谈到高并发的解决方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也 ...
- C++高并发场景下读多写少的优化方案
概述 一谈到高并发的优化方案,往往能想到模块水平拆分.数据库读写分离.分库分表,加缓存.加mq等,这些都是从系统架构上解决.单模块作为系统的组成单元,其性能好坏也能很大的影响整体性能,本文从单模块下读 ...
- 并发场景下HashMap死循环导致CPU100%的问题
参考链接:并发场景下HashMap死循环导致CPU100%的问题
随机推荐
- [日常摸鱼]Luogu2878 [USACO07JAN]Protecting the Flowers
直接贴题面x 有$n$头奶牛跑到FJ的花园里去吃花儿了,它们分别在距离牛圈$T$分钟处吃花儿,每分钟会吃掉$D$朵卡哇伊的花儿,FJ现在要将它们给弄回牛圈,但是他每次只能弄一头回去,来回用时总共为$2 ...
- [水题日常]Luogu1462 通往奥格瑞玛的道路
QwQ马上高二啦不能颓啦-知乎上听说写博客的效果挺好的,来试一下好啦~ 题目链接<< 题目描述 在艾泽拉斯,有n个城市.编号为1,2,3,...,n. 城市之间有m条双向的公路,连接着两个 ...
- Java源码赏析(六)Class<T> 类
目的 Class 类是每一个程序员都必须了解的,也是使用反射机制的基础. 这篇文章将Class 类的公共方法大致介绍了一遍(省略了安全.枚举.断言.注解相关代码). 代码 package java.l ...
- 个人微信公众号搭建Python实现 -个人公众号搭建-运行run方法的编写(14.3.3)
@ 目录 1.主要逻辑 2.代码 关于作者 1.主要逻辑 使用的是flask服务器 就使用一个函数处理请求 第一个是验证服务器,返回微信服务器给的字符串就表示验证成功 第二是要处理微信服务器发送过来的 ...
- Spring MVC整合 freemarker
1.什么是Spring MVC? Spring MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦,基于请求驱 ...
- Gopher协议在SSRF漏洞中的深入研究
如果需要大佬写好的脚本,可以直接去github上面搜 参考文章:https://zhuanlan.zhihu.com/p/112055947 https://www.cnblogs.com/Konmu ...
- Loki 初体验
Loki 是什么 Loki 是 Grafana Lab开发的一套日志系统,使用Go语言实现.根据官方的介绍, Loki,高可用性,多租户的日志聚合系统,受到Prometheus的启发.它的设计非常经济 ...
- 在 WSL Ubuntu 上使用 .NET 进行跨平台开发新手入门
翻译自 haydenb 2020年6月3日的文章<Getting started with cross-platform development using .NET on Ubuntu on ...
- flowable中传入审批人是list
package org.springblade.flow.engine.listener; import org.flowable.engine.delegate.DelegateExecution; ...
- 【探索之路】机器人篇(4)-根据3D文件来优化自己的机器人模型
此章节不是必须做的!!!! 因为我已经用solidworks画了机器人的3D模型,那我就直接导入已经画好的三维模型. 如果大家没有画也是可以直接使用上一章节我们已经构建的机器人模型.我这里只是一个对显 ...