首页 > 编程源码 > ThreadLocal原理浅析

ThreadLocal原理浅析

楼主:阿西西. [1级] · 2019-9-30 ·  浏览628 · 编程源码 · ID:

Thread ,ThreadLocalMap,Entry三者关系
其实研究下来他的源码实现,其实也没想象的那么复杂,其最主要有以下几点:

1、Java可以通过Thread.currentThread()来获得当前的Thread的实例对象。既然能拿到这Thread对象实例,那么我们就可以操作该实例(的属性),比如为该Thread对象设置一个值什么。

2、每一个Thread对象都有一个ThradLocalMap实例,该实例有一个一个Entry组成的数组,Entry对象有两个主要属性:value和ThreadLocal的弱引用,其中value这个属性就是值设置给当前线程所持有,也是ThreadLocal的核心属性:

注意Entry继承自WeakReference,其key就是ThreadLocal对象!

结合1和2两个知识点,我们就可以知道我们拿到Thread对象之后,就可以操控当前线程对象的ThreadLocalMap对象,然后把想要保存的value交给ThreadLocalMap的Entry的value属性,Thread,ThreadLocalMap,value三者之间的关系可以用下图表示

通过上图我们可以得出这么一个结论:一个Thread对象持有一个ThreadLocalMap对象,然后呢,一个ThreadLoalMap对象又包含了多个ThreadLlocal对象及ThreadLocal对象所在线程的value!!!一言以蔽之: 一个Thread对象可以持有多个ThreadLocal对象的变量值value

那么ThreadLocal和Thread又有啥关系呢?二者是怎能对value进行读取的呢?下面就根据源码来简单的分析下。

ThreadLocal和Thread的关联
先看看ThreadLocal的set方法:

set方法很逻辑很简单(j结合上图2看更好理解):
1、通过currentThread方法拿到当前Thread对象
2、获取当前Thread对象的ThreadLoalMap对象
3、将value连同ThreadLocal对象自己组成一个Entry对象保存在
ThreadLoalMap的Entry类型的数组中。

在来看看ThreadLocal的get方法

可以发展get的整体逻辑也很简单:
1、获取当前Thread对象
2、获取当前Thread对象的ThreadLocalMap对象
3、从ThreadLocalMap中获取与ThreadLocal相关联的Entry对象,具体的就是以ThreadLocal为key获取。
4、获取步骤3的Entry的value属性,并返回之。

通过整体观察get和set方法可以得出如下结论:ThreadLocal对象调用set方法就是往Thread对象的ThreadLocalMap里面添加值;ThreadLocal对象调用get方法就是从Thread对象的ThreadLocalMap里面获取值。核心就是操纵Thread对象的ThreadLocalMap对象进行value的读和写。原理就这么简单。

那么位于不同线程的不同ThreadLocal对象,在其他线程里保存值是一个什么样的关系呢?可以通过下图来清晰的描述出来:

通过上图可以知道我们在线程X里面定义了一个threadLocalX的变量,然后线程A调用threadLocalX的set方法将x1这个值设置给了线程A,线程B同样调用threadLocalX的set方法将x2这个值这是给了线程B.当我们操纵threadLocalX的get方法来取值的时候,此时get方法运行在哪个线程,取得就是哪个线程保存的值,比如如果此时A线程在执行,那么拿到的值就是x1.

ThreadLocal的使用实例
我们在知道在Android中一个线程只有一个Looper对象,那么是怎么做到的呢?就是ThreadLocal发挥了作用,看看Looper的prepare方法:

观察prepare方法可以知道,先通过sThreadLocal的get方法判断当前线程是否已经拥有了一个Looper对象,如果有就抛出一个异常;如果当前线程还没有设置Looper对象,则调用ThreadLocal的set方法,初始化一个Looper对象交给当前线程:sThreadLocal.set(new Looper(quitAllowed));
这样就确保了一个线程只有一个Looper对象。

到此为止,关于ThreadLocal的原理已经基本分析完毕,至于内部是怎么set和get的,博主并没有做太细的分析,因为没必要,了解ThreadLocal的工作原因以及使用场景即可。
- 版权声明 - 1、本帖所有言论和图片等纯属网友个人意见,与流星社区立场无关;
2、其他单位或个人使用、转载或引用本帖时必须同时征得该帖子作者阿西西.流星社区的同意;
3、备注原文地址:https://bbs.liuxingw.com/t/14833.html,可忽略第2条;
4、帖子作者需承担一切因本文发表而直接或间接导致的相关责任;
5、如本帖内容或部分内容转载自其它媒体,这并不代表本站赞同其观点和对其真实性负责;
6、如本帖若为资源类,将仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您安装或使用的设备中彻底删除上述内容;
7、如果您喜欢该程序,请支持正版软件,购买注册,可以得到更好的正版服务;
8、如本帖侵犯到任何版权或违法问题,请立即邮件告知我们,我们将及时予以处理。
7条回复 |  最后回复于2019-9-30

肤浅‮‭ [1级]

你的互关【肤浅大帅比】来给你顶帖送星币啦!
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

阿西西. [1级]

楼上都是憨憨
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

[]

楼上都是憨憨
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

花 姬 [2级]

上面全是铁憨憨
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

阿西西. [1级]

等会头给你打歪
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

花 姬 [2级]

反弹
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...

八日蝉ヾ [2级]

谁TM要是让我改线程,头能给他打歪
发布于2019-9-30

回复列表

  • 内容加载中...

说点什么...
登录注册 后才可进行评论
签到
8人签到
已签0天
  • 46611帖子
  • 1936533热点量
  • 184839火热值