ThreadLocal引起的一次线上事故 (2)

那么既然是没有被更新,到这里我们就很好解决了,要么每次使用完成后都将ThreadLocal中的数据remove。因为他内部是弱引用在下次回收就会将对象回收这样也不会造成内存泄漏的问题

或者我们在我们的AOP中setUser之前先将用户ThreadLocal清空。两种方式都可以完美解决我们的问题

具体代码实现 /** * 请求生命周期最后一步销毁是做的回调事件 * 用于销毁在线用户信息,防止在线用户信息互相干扰(在多线程复用时) */ @WebListener @Primary public class SysServletRequestListener implements ServletRequestListener { @Override public void requestDestroyed(ServletRequestEvent requestEvent) { UserInfoUtil.clearUserInfo(); } @Override public void requestInitialized(ServletRequestEvent sre) { } }

我们可以通过spring提供的监听器,监听一个请求的生命周期在这个请求完成之后将我们的ThreadLocal进行remove。 为什么我推荐这种做法呢。因为请求结束就清空可以快速的让出内存让他去做更加有用的事情。

如果是第二种方法那么如果我们没有人在登录,或者说在下一次登录之前这块不需要的内存永远被占着

总结忠告

这次问题出现的很是奇怪,一度让我怀疑人生,但是永远相信程序是不会无缘无故的出问题的。

出问题的只能是我们的代码有问题,要善于解析问题,将问题细化,细化到我们代码层面而不是业务层面

使用一个技术时最好能先了解他内部的一个原理。或者最起码先了解他的大概逻辑

别看这篇文章寥寥几字就解决了我们的问题,但是实际上我在解决他的过程中吃了不少的苦。好几个夜晚都是我在陪他战斗

我在定位到时ThreadLocal后就花了一个小时学习了下他的逻辑并跟踪了他的源码。最后结合我们的业务才发现了眉目

总之有问题是好事情,有了问题我们才能成长。至少在这次的问题中我学习到了ThreadLocal。我的这次问题也是使用他的典型问题,另外还有一个内存泄漏的问题这是在学习他源码的过程领悟到的一点。关于内存泄漏我们有时间在看吧。问题解决。终于可以继续happy了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfzwj.html