大白 大白共图社 5月30日
还不懂ThreadLocal?
平常一些业务代码中经常会出现对JDK组件ThreadLocal的使用。那么对ThreadLocal的理解就显得刻不容缓了,那接下来我们要通过源码去剖析?还是要通过实例代码去分析?
答案:都不是。
读源码太枯燥,看实例又无趣。 那我们怎么去理解?
用什么样的思维去读ThreadLocal?
当然是通过超级简单易懂的面向都对象思想去理解了,好吧,你还是逃不过看代码,但却不难:
public class Dog{
String breed;
int age;
String color;
void barking(){}
void hungry(){}
void sleeping(){}
}
类的作用我们都知道,它封装了数据和方法,即属性和行为。所以不管是看到什么业务层代码也好,技术层代码也好,我们思维是:这个类的属性和行为是什么?这个类在整个体系中是什么角色?而且更重要的思维是:它们有哪些内部联系?
ThreadLocal机制的两个角色
来看下我们需要分析的类
ThreadLocal
{
//每个ThreadLocal对象的该字段
//值都是唯一的,创建
//对象的时候给这个属性赋值
final int threadLocalHashCode;
//所有ThreadLocal对象共享的
//静态整数
//用于threadLocalHashCode
//的值的计算
AtomicInteger nextHashCode;
//线程专属数据的获取
get();
//线程存储专属的数据
set();
}
Thread
{
//用于维护线程专属的数据
ThreadLocalMap threadLocals ;
//获取当前方法所在的线程对象引用
native currentThread();
}
如果要分析Thread Local,那就不得不结合Thread来一起分析,因为ThreadLocal的get方法获取的数据不是由ThreadLocal对象维护的,而是维护在Thread的对象内,即thradLocals属性内,这个属性是个Map类型数据,可以维护多种数据。
看到这里大家或许会有疑问,我们的很多业务代码都没有Thread这个类对象存在,那这里谈Thread这个类是为什么呢?这里要补充一个非常重要的概念:JVM中所有的java代码都是运行在一个java的线程中,即而静态本地方法currentThread是指向这个线程的索引。
tips:
1.每个ThreadLocal对象都维护着一个唯一的id值(整型)。
2.get方法是通过这个id值从对应的Thread对象中获取数据。
3.Thread对象通过Map属性维护线程对象专属的数据,而每个Threadlocal对象通过id值去map中取出相应的数据。
ThreadLocal机制中的角色
ThreadLocal其实就是个打长工的,而Thread是个地主土财主,所有的粮食都放在自己专属的10个仓库里,每个仓库都有一个唯一的钥匙(key);在一个大家族里面,5个土财主都是亲兄弟,家族里雇了10个长工,每个长工保管5个地主的仓库钥匙:1号长工保管着5个地主的1号仓库,以此类推到10号。
每个地主如果想要吃哪个仓库的粮食了,那么他只要吩咐管理这个仓库的长工去取粮食就行了,自己啥也不用干。这个故事的架构图大致如下,有点粗鄙,将就着看。
娱乐和内核
即使在平时休闲娱乐的时候,坐地铁的时候,上电梯的时候,你也能够用来提高自己,我写文章最大的追求不是希望读者朋友记住所有的知识,而是吸收了所有知识围绕的内核—思维。不需要记忆,不需要copy,只要能体会提到的这些思维就是这个文章最大的成功!
思维是:这个类的属性和行为是什么?它在整个体系中是个什么样的角色,承担着什么职责?而且更重要的思维是:它们有哪些内部联系?
talk is cheap ,show you the code and the doc,更多的分享内容请关注我的工作号:大白共图社。公众号会有很多的github开源社区拿来即用项目源码以及相关的文章。欢迎关注。