ThreadLocal简单理解

每次背面试题,老是记不住ThreadLocal相关的知识,还是没有熟练掌握的原因,这里总结了几个大佬的知识,写下自己的理解。

为什么要用到ThreadLocal?

线程A和线程B都要用到变量C,但是线程A不小心修改了变量C,那线程B就傻眼了,所以出于线程安全的问题,这地方是不需要将变量C进行共享的,那怎么办?假如每个线程中都有一个变量C,并且各个线程之间对变量C的修改访问是互不影响的,即线程隔离。

而我们的ThreadLocal就是解决这个问题的,在代码中任何一处声名的ThreadLocal都可以实现线程隔离的变量。

ThreadLocal简单用法:

String localVar = "123";
ThreadLocal<String> threadLocalObject = new ThreadLocal<String>();
threadLocalObject .set(localVar);

String str = threadLocalObject .get();

ThreadLocal相当于一个工具类,将我们线程要用的变量通过set方法存在线程中,通过get方法拿到变量的值。

那么ThreadLocal是怎么存储的呢?

实际上并不是ThreadLocal存储的,每个Thread都有一个ThreadLocalMap类型的threadlocals成员变量,它存储了本线程中所有的threadlocal对象和对应的值,而ThreadLocalMap是由一个个Entry构建的,key是ThreadLocal对象,value是ThreadLocal对象对应的值。entry是一个弱引用。

这么说起来有点抽象,上图:

其中两个线程虽然操作的是同一个ThreadLocal对象,但是他们访问修改是互不影响的

private static ThreadLocal<String> sThreadLocal = new ThreadLocal<>();
private static ThreadLocal<String> sThreadLoca2 = new ThreadLocal<>();
Stirng str = "测试相同字符串"
    public static void main(String args[]) {
        sThreadLocal.set("这是在主线程中");
        System.out.println("线程名字:" + Thread.currentThread().getName() + "---" + sThreadLoca2.get());
        System.out.println("线程名字:" + Thread.currentThread().getName() + "---" + sThreadLocal.get());
        //线程a
        new Thread(new Runnable() {
            @Override
            public void run() {
                sThreadLocal.set("这是在线程a中");
                System.out.println("线程名字:" + Thread.currentThread().getName() + "---" + sThreadLoca2.get());
                System.out.println("线程名字:" + Thread.currentThread().getName() + "---" + sThreadLocal.get());
            }
        }, "线程a").start();
线程名字:main---测试相同字符串
线程名字:main---这是在主线程中
线程名字:线程a---测试相同字符串
线程名字:线程a---这是在线程a中

上面代码相当于下图:

一个ThreadLocal对应着一个变量,如果我们想存多个变量,就多创建多个ThreadLocal,实际上是放在map当中,不用我们担心,不过太多ThreadLocal对象,会导致内存泄露问题,不过这个Entry是个弱引用,也不用我们担心。

关于ThreadLocal内存泄露:(简单谈一下)

由于ThreadLocalMap的生命周期跟Thread一样长,如果没有手动删除对应key就会导致内存泄露,而不是因为弱引用。跟强弱引用根本没有关系。

引用某位大佬的一段话:

以上为自己的理解,欢迎各位大佬来指点,谢谢

参考文章:

到底为什么我们需要ThreadLocal?_为什么要使用threadlocal-CSDN博客

史上最全ThreadLocal 详解(一)-CSDN博客

Thread ThreadLocal和ThreadLocalMap,用法+原理,我懵圈了? - 知乎 (zhihu.com)

(21 封私信) ThreadLocal一个线程只能存放一个变量吗?想存多个怎么搞? - 知乎 (zhihu.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值