ThreadLocal引起的问题
来源:互联网 发布:caffe数据层参数 编辑:程序博客网 时间:2024/05/01 08:33
我们曾经做过一个多租户的项目,每个租户用一个唯一的平台号。程序中有的地方把当前用户的平台号放在一个ThreadLocal变量中。部署到tomcat上后发现一个很奇怪的现象:有时候用户的平台号会出现错乱,即一个人的平台号会出现在另一个登录用户的身上。最后发现问题出在线程池上。
大家知道ThreadLocal中的值实际上保存在线程对象中。在有线程池的情况下,线程用完后会还到线程池中,下一次需要线程时就从线程池中获取一个。如果ThreadLocal中的值上次没清空,这个值就会保留下来继续被使用。就是这个原因导致ThreadLocal中的数据混乱的。
原因清楚了,解决方法也就很简单了。ThreadLocal使用完后把值清除即可。
为简化问题,可以写一个ThreadLocalRegistry负责记住所有需要清除的ThreadLocal,然后在ThreadLocalCleanerInterceptor中统一清除。代码如下:
public class ThreadLocalRegistry {private static ThreadLocal<List<ThreadLocal>> threadLocals = new ThreadLocal<List<ThreadLocal>>();public static void register(ThreadLocal threadLocal) {synchronized (threadLocals) {if (threadLocals.get() == null) {threadLocals.set(new ArrayList<ThreadLocal>());}threadLocals.get().add(threadLocal);}}public static void clear() {synchronized (threadLocals) {if (threadLocals.get() == null) {return;}for (ThreadLocal threadLocal : threadLocals.get()) {threadLocal.remove();}threadLocals.get().clear();threadLocals.remove();Guzz.setDBGroup(null);Guzz.setTableCondition(null);}}}
public class ThreadLocalCleanerInterceptor implements Filter {public void destroy() {}public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {try {chain.doFilter(req, res);} finally {ThreadLocalRegistry.clear();}}public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {try {chain.doFilter(request, response);} finally {ThreadLocalRegistry.clear();}}@Overridepublic void init(FilterConfig config) throws ServletException {}}
0 0
- ThreadLocal引起的问题
- 不同请求获取到了相同的ThreadLocal值引起的问题
- ThreadLocal可能引起的内存泄露
- ThreadLocal可能引起的内存泄露
- 关于ThreadLocal内存泄漏引起的思考
- ThreadLocal可能引起的内存泄露
- ThreadLocal可能引起的内存泄露
- 关于ThreadLocal引起内存泄漏的理解
- 【并发】ThreadLocal可能引起的内存泄露
- ThreadLocal可能引起的内存泄露
- scanf()引起的问题
- size_t引起的问题
- BuildPath引起的问题
- fork引起的问题
- tcp_timestamps 引起的问题
- 硬件加速引起的问题
- __packed引起的问题
- samba引起的问题
- 虚拟机windows server2003下使用PoolMon排查内存问题
- java基础知识-方法与数组
- Android 出现NetworkOnMainThreadException
- C++复习0.3——模版/类型转换/异常
- js对日期函数的操作API
- ThreadLocal引起的问题
- RHCSA小测试
- css 360浏览器模式控制
- 基本类型包装类及自动装箱拆箱
- [HDU1269]迷宫城堡(Tarjan)
- <unity shader入门精要>
- 虚拟存储器(二)——Linux虚拟存储器系统
- PHP生成唯一ID的三种方法
- jQuery - 列表控件推荐