首页 > 其他分享 >【线程池】使用ThreadLocal请务必remove

【线程池】使用ThreadLocal请务必remove

时间:2023-03-27 17:01:45浏览次数:42  
标签:请求 get controller remove ThreadLocal 线程

背景:

在一次扫描中被提示: Field [SESSION_CONTEXT] of type ThreadLocal must call remove() method at least one times. (line 34)
嗯?啥子情况?

搜索了一下,发现:

ThreadLocal 属于线程,于线程创建而生,线程结束而自然销毁,本来是没什么问题的。
但是, 但是如果是在线程池中的线程,就会产生问题。
因为:线程池里面的线程是重复使用的,线程并不会因为用完了销毁,而是会放回线程池,那意思就是说,这个 ThreadLocal 里面放的数据,它也在!如果下一个请求来了,还是从线程池中拿到这个线程,那即使它还没有产生任何数据,ThreadLocal 里面却已经存在了上一次请求的数据,这个时候,可能会出现问题。

为什么说是 “可能”呢?

因为这得分情况来看:
情况1:请求进来,使用ThreadLocal,先 set 再 get , 这个时候,没有问题。因为先写再读,它即使一开始带了上个请求的数据,但会更新为自己正确的数据,再读取,oK,没有问题。
情况2:请求进来,使用ThreadLocal,先 get ,做一些操作了,再 set , 那么这个时候,就会有问题了,因为它会拿到上个请求的数据去做自己的业务,这可能就会产生奇奇怪怪的问题了。

怎么办?

使用 ThreadLocal, 每次用完后,就调用 remove 方法, 将其删掉,避免产生先 get 后 set 的情况,导致业务逻辑错误,还不太好排查。

用完就清,还有一个好处:

就是能够比较好避免堆溢出。原因,也不难理解,因为如果每个线程进来,用了又不删除掉,也无法释放,那这个 ThreadLocal (也就是一个Map),放的数据就会越来越多,占用堆内存也会越来越大。


引用:

《Java并发编程实战》一书的第8章时,有如下一句话:

只有当线程本地值的生命周期受限于任务的生命周期时,在线程池的线程中使用ThreadLocal才有意义,而在线程池的线程中不应该使用ThreadLocal在任务之间传递值。

嗯。反正 ThreadLocal 以后使用时,无论是先 get 还是 先 set 都建议用完清空一下。
(记录一下)


再说多两句,
说是说 ThreadLocal 用完要 remove, 但这个边界—— 什么时候才算是用完呢?
一开始确实是迷惑了一下,如果还没有用完,先 remove 掉了,那肯定会出问题的。

说一下,我遇到的这个场景,
这个 case 是在一个 controller 拦截器上做的业务,进入 controller 方法前,做一些判断,然后通过了就进入 controller, 然后再到下一个请求进来这个 controller。

那这个场景下,什么时候算是结束?
我理解就是:这个拦截切面 @after 方法就好了。完成 controller 方法之后。

标签:请求,get,controller,remove,ThreadLocal,线程
From: https://www.cnblogs.com/aaacarrot/p/17262135.html

相关文章

  • 原来还能这样看Java线程的状态及转换
    作者:小牛呼噜噜|https://xiaoniuhululu.com计算机内功、JAVA底层、面试、职业成长相关资料等更多精彩文章在公众号「小牛呼噜噜」大家好,我是呼噜噜,最近一直在梳理Jav......
  • 线程安全
    1.代码所在的进程含有多个线程,线程可能会同时运行这段代码,若所有的运行结果是相同的,且其他变量的值也和预期的是一样的,就是线程安全的。2.通常线程不安全的对象都是由全......
  • 线程和进程的区别【Android面试送命题】
    这道题面试出现的概率是百分之70下面我来讲下如何回答1,进程是资源管理的最小单位,线程是程序执行的最小单位2,每个进程都有自己的数据段代码段和堆栈段。线程通常叫做轻型......
  • 多线程
    1、概念线程:线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。进程:进程是程序的基本执行实体。多线程:有了多线程,就可以让程序同......
  • start线程开启(C源码分析)
    一个线程开启都经历了什么publicclassThreadBaseDemo{publicstaticvoidmain(String[]args){Threadt1=newThread(()->{},"t1");......
  • 多线程的同步和互斥—线程的信号量
    同步://account.h#ifndef_ACCOUNT_H#define_ACCOUNT_H#include<pthread.h>#include<semaphore.h>typedefstruct{intcode;doublebalance;......
  • Python多任务-多线程-多进程-协程-进阶学习
    --多任务-多线程-多进程-协程-进阶学习--文中所提到的案例参考:GITHUB中项目文件夹https://github.com/FangbaiZhang/Python_advanced_learning/tree/master/02_Python_ad......
  • Task 类 多线程
    Task类定义命名空间: System.Threading.Tasks程序集:System.Runtime.dll表示一个异步操作publicclassTask:IAsyncResult,IDisposable继承  Object->Task......
  • 线程(确实还有没理解到位的地方)
    多线程Thread类多条执行路径,主线程和子线程并行交替执行packagexiancheng;publicclassDemo01extendsThread{//创建线程方式一:继承Thread类,重写run方法,调用s......
  • 多线程的互斥—读写锁
    //account.h#ifndef_ACCOUNT_H#define_ACCOUNT_H#include<pthread.h>typedefstruct{intcode;doublebalance;//定义一把互斥锁,用......