threadLocal遇上线程池导致局部变量变化

最近遇到一个比较隐蔽而又简单地问题,在使用ThreadLocal时发现出现多个线程中值串来串去,排查一番,确定问题为线程池的问题,线程池中的线程是会重复利用的,而ThreadLocal是用线程来做Key的所以在使用线程池的时候要特别注意ThreadLocal.

Servlet处理请求时也是以线程池为每次请求提供线程,所以如果有使用到ThreadLocal的话,需要注意这一点。

对于上述情况,需要我们在每次请求发起时,重新设置ThreadLocal里的值,这样才能保证每回获取到的是当前用户的信息,而非线程上次设置的值。ThreadLocal声明周期也应该为每次请求中。

新加一个ThreadLocalRequest用来记录当前请求的request的引用。如果当前代码执行的线程还属于同一次请求则不更改重置ThreadLocal中的变量。如果当前线程不属于同一次请求,则重置ThreadLocal的变量。

因为有时候一个实例在一次请求中会出现被调用多次的情况,所以需要区分线程当前处理是否同一次请求。不是同一次请求,可能ThreadLocal保存的请求信息是不同的,例如用户信息。不同用户的请求可能会共用线程池中的同一个线程去处理,这时候需要重置线程本地变量。

    if(threadLocalRequest.get()!=null&&(threadLocalRequest.get()!= this.pageContext.getRequest())){         
            if (threadLocalVar.get() != null) {
                threadLocalVar.remove();
            }
     }
    if(threadLocalRequest.get()==null){
        threadLocalRequest.set(this.pageContext.getRequest());
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值