ThreaLocal使用与讲解

我们经常听说可以使用ThreaLocal解决多线程的线程安全问题,ThreaLocal为什么可以解决这个问题以及具体怎么使用呢?

一般提到多线程自然而然就会想到锁机制,那么这里为什么不用锁而是用ThreaLocal呢?这里就涉及到ThreaLocal的使用场景了,其实ThreaLocal设计目的和使用场景是实现一个线程内部变量的共享,跟多线程之间共享变量完全是两码事。

那么线程内部变量为什么要共享?共享给谁?为什么要共享那当然是需要用到这个变量值,共享给这个线程中运行的所有方法。这里其实会涉及到Java内存模型相关的知识,为了方便理解举一个例子:假设A方法中定义了一个变量,再后续的B、C、D方法中都会用到这个变量,我们常用的办法都是将这个变量通过方法参数传递。每次都要传很多参数比较繁琐,那有没有可以不用传这个参数,但需要用到的时候又可以拿得到呢?答案是肯定的,那就是ThreaLocal。

我们可以将后续需要用到的变量放到ThreaLocal中,准确的说是放到当前线程Thread的一个成员变量ThreaLocal.ThreaLocalMap threadlocals里面(这个有点绕,比理解先跳过,就当作是放在ThreaLocal里)。这时候你会不会有一个疑问:那是不是还得把ThreaLocal往后面的方法传呢?自然是不用的,如果这样做跟直接传变量就没啥区别了,相当于又回到了原点。

不用传参那具体怎么用呢?聪明的你应该想到了,把变量定义为static的。这样就可以做到不用传参数,又随时可以拿到,跟平时定义一个常量类的玩法一样。看到这里如果觉得豁然开朗或者觉得讲了半天废话,都一定要往下看,因为这是一个很好的思维锻炼过程。

先休息一下吧
在这里插入图片描述

上面相当于讲到了为什么要用ThreaLocal,答案是为了省去传参的麻烦;以及解决思路,那就是把变量定义为静态的。貌似问题都迎刃而解了,再仔细想想发现使用静态变量为什么要用ThreaLocal?自己随便定义一个类都可以用来封装静态变量。因为定义为静态变量就以为着这个变量是线程之间共享的了,那就会线程安全问题,ThreaLocal自然而然就是可以帮助我们方便解决线程安全问题的。

这个时候再去看ThreaLocal原理应该会好理解很多,不然看了一堆博客还是似懂非懂,完全也不知道该怎么用,过几天就会忘记或者搞不清楚那些很绕的原理,面试时一问就懵了。

下面通过一个实例来讲解一下具体用法。比如用户登录之后,用AdminUser类来封装这个用户的所有信息,后续的很多操作都需要用到AdminUser中的信息,但又不想一直传这个参数,那就可以使用ThreaLocal。代码如下

public class AdminHolder {

    private static ThreadLocal<AdminUser> userThreadLocal = new ThreadLocal<AdminUser>();

    private static ThreadLocal<HttpRequest> requestThreadLocal = new ThreadLocal<HttpRequest>();
    // 添加需要共享的变量
    public static void addValue(AdminUser adminUser) {
        userThreadLocal.set(adminUser);
    }
    public static void addValue(HttpRequest request) {
        requestThreadLocal.set(request);
    }
    // 获取共享的变量
    public static AdminUser getAdminUser() {
        return userThreadLocal.get();
    }
    public static HttpRequest getHttpRequest() {
        return requestThreadLocal.get();
    }
    // 清楚共享的变量
    public static void remove() {
        userThreadLocal.remove();
        requestThreadLocal.remove();
    }
}
class AdminUser{
    // 有各种成员变量信息
};
class HttpRequest{
    // 有各种成员变量信息
};

通过AdminHolder类的get方法就可以获取到想要共享的变量了,那在哪里设置这些变量值呢?像上面这个例子可以定义一个LoginFilter,在里面获取到用户信息和请求信息,然后添加到AdminHolder里。

到目前为止ThreaLocal使用就讲完了,看完这篇文章再去看ThreaLocal原理相信会更好理解。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值