ThreadLocal详解

ThreadLocal是Java中用于线程内部变量的一个工具类,它保证了线程间的变量隔离。文章详细介绍了ThreadLocal的使用场景,如数据传递和方法拦截,以及Thread、ThreadLocal、ThreadLocalMap和Entry之间的关系。同时,文章探讨了ThreadLocal的创建、set、get和remove方法的工作原理,包括哈希冲突的处理和内存泄露的解决方案。

1.简介

​ 在项目开发中,有时候一个方法中设置或者初始化的值,在调用其它很多方法时,都需要使用此值,此时可以通过传参的方式一直传递下去,但这样增加了传递的复杂度和耦合度;aop在调用之前设置某些值,在调用结束或抛出异常时需要使用此值。对于这些场景,都可以使用ThreadLocal来实现。

​ ThreadLocal是用来操作线程Thread内部变量threadLocals的工具类,ThreadLocal设置变量、获取变量之前,都需要先获取当前线程Thread.currentThread(),然后操作当前线程的内部变量threadLocals进行存取,这样就能保证线程的变量独立于其它线程,对其它线程是隔离的,在自己线程内共享变量,在线程生命周期内起作用。

2.使用案例

(1)数据传递

​ 在方法中传递参数或者跨层传递参数,使用ThreadLocal存取值。

public class ThreadLocalDemo {
   
   

    public static void main(String[] args) {
   
   
        Demo1 demo1 = new Demo1();
        demo1.test("张三");
        //使用完成移除ThreadLocal
        ThreadLocalHolder.threadLocal.remove();
    }
}

class Demo1{
   
   
    public void test(String name){
   
   
        ThreadLocalHolder.threadLocal.set(name);
        System.out.println("demo1设置的值:"+name);
        Demo2 demo2 = new Demo2();
        demo2.test();
    }
}

class Demo2{
   
   
    public void test(){
   
   
        String name = ThreadLocalHolder.threadLocal.get();
        System.out.println("demo2取到值:"+name);
        Demo3 demo3 = new Demo3();
        demo3.test();
    }
}

class Demo3{
   
   
    public void test(){
   
   
        String name = ThreadLocalHolder.threadLocal.get();
        System.out.println("demo3取到值:"+name);
    }
}

//构造ThreadLocal的提供类
class ThreadLocalHolder{
   
   
    //定义类型为String的ThreadLocal
    public static final  ThreadLocal<String> threadLocal = new ThreadLocal<String>();
}

​ 输出结果:
在这里插入图片描述
(2)方法拦截

​ 拦截器输出服务接口响应时间,需要在拦截器中的preHandle()方法执行之前记录下时间,在afterCompletion()请求处理结束方法中使用当前时间减去开始时间来计算接口响应时间。

@Slf4j
@Component
public class HttpLogHandlerInterceptor implements HandlerInterceptor {
   
   

    //定义类型为LocalDateTime的ThreadLocal
    private final static ThreadLocal<LocalDateTime> startTimeLocal = new ThreadLocal<>();

    //接口被调用处理之前的拦截器
    @Override
    public boolean preHandle(@NotNull HttpServletRequest request,
                             @NotNull HttpServletResponse response,
                             @NotNull Object handler) {
   
   
        //当前时间设置到ThreadLocal中
        startTimeLocal.set(LocalDateTime.now());
        //输出日志信息
        log.info("starting request.url:{},client addr:{},host addr:{}",
                request.getRequestURL(), request.getRemoteAddr(), request.getLocalAddr());
        return true;
    }

    //请求处理结束之后的拦截器
    @Override
    public void afterCompletion(@NotNull HttpServletRequest request
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值