浅看ThreadLocal

本文详细解析了Java中的ThreadLocal机制,包括其如何实现线程间数据隔离,涉及的主要类如ThreadLocal、ThreadLocalMap和Entry,以及get、set、remove方法的工作流程。此外,还介绍了InheritableThreadLocal的特性,它允许子线程继承父线程的变量。最后提到了Netty的FastThreadLocal,其在特定场景下可能比标准的ThreadLocal更高效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了下ThreadLocal的源码,对这个有了一个基本的了解。

只简单的追了一下源码,解析得不到位,各位要深入了解的可以看看源码和看看大佬的解析。

ThreadLocal提供了线程的局部变量,让每个线程通过get/set来操作这个局部变量;不会和其他线程的局部变量冲突,实现线程的数据隔离。
主要涉及到4个类,分别是:Thread、ThreadLocal、ThreadLocalMap、Entry。
其中ThreadLocalMap是ThreadLocal的静态内部类,Entry是ThreadLocalMap的静态内部类。

ThreadLocal类中,主要的3个方法:T get()、void set(T value)、void remove()
分别代表 取数据、存数据、删除数据。

先把Thread类的源码放这里,里面有这样2个属性,后面会用到。
在这里插入图片描述
ThreadLocal可以让每个线程又自己的私有数据 =》 threadLocals
InheritableThreadLocal可以让子线程获取到父线程的私有数据 =》 inheritableThreadLocals

set方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这个流程很容易理解,首先获取当前线程,然后获取线程中的threadLocals属性,返回的就是一个ThreadLocalMap,然后判断是否为null,创建或者调用ThreadLocalMap的set方法设置值,初始的时候都是null的,初次使用或者在构建时进行初始化。
在这里插入图片描述
在这里插入图片描述
可以看到,ThreadLocalMap的set方法,将ThreadLocalMap作为key,值作为value封装成一个Entry对象进行存储,存的地方就是上面的 private Entry[] table 里面,其中key是弱引用。

get

在这里插入图片描述
也是先获取当前线程,从当前线程中获取到ThreadLocalMap属性;如果map是null的,就设置个初始化的值(也就是null);
如果不是null的,计算下标,从table中获取对应的Entry对象,从中取值;
在这里插入图片描述
如果Entry存在,并且引用还存在(key是弱引用,容易被回收)且是传入的ThreadLocalMap引用,直接返回该Entry对象;
在这里插入图片描述
在这里插入图片描述
会清除不用的数据。

remove:

在这里插入图片描述
还是根据当前线程获取对应的ThreadLocalMap,调用ThreadLocalMap的remove方法;
在这里插入图片描述
清除数据

InheritableThreadLocal

InheritableThreadLocal继承自ThreadLocal,仅重写了一下3个方法
在这里插入图片描述
创建线程时,如果父线程的inheritableThreadLocals不是null,会将父线程的inheritableThreadLocals传递给子线程
在这里插入图片描述
子线程将父线程的所有变量复制一份
在这里插入图片描述
InheritableThreadLocal在线程池中使用要特别注意。它是在初始化的时候复制的父线程的数据,后期就不会主动变化了,所以在第一次调用线程池的线程执行任务时初始化,后面即使再调用,也只是第一次调用时的父线程的数据。
通过这个来获取比如当前用户信息等就可能出现问题。

后续补充:

今天(2021-12-28)有看到一篇文章写的是netty的FastThreadLocal,这玩意儿用法几乎跟JDK的ThreadLocal没啥区别,只是不能使用JDK的Thread,而是要使用netty的FastThreadLocalThread,这个类继承自Thread;FastThreadLocal用好了据说要比JDK的ThreadLocal快很多。
参考原文:https://blog.youkuaiyun.com/lirenzuo/article/details/94495469
https://juejin.cn/post/7023921712467017741

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值