设为首页
收藏本站
切换到宽版
登录
立即注册
找回密码
搜索
搜索
本版
帖子
用户
快捷导航
论坛
BBS
VIP用户组
官网群
无名商城论坛
»
论坛
›
资源分享区
›
学习资源专区
›
ThreadLocal原理浅析
返回列表
发帖
查看:
412
|
回复:
0
[其他技术]
ThreadLocal原理浅析
[复制链接]
无名
无名
当前离线
积分
32464
1万
主题
1万
帖子
3万
积分
管理员
积分
32464
发消息
发表于 2022-5-8 18:55:33
|
显示全部楼层
|
阅读模式
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的工作原因以及使用场景即可。
对象
,
ThreadLocal
,
线程
,
一个
,
Thread
相关帖子
•
【Max】团队~利用AIDE做个小应用=总结+AIDE教程结束
•
【LUR】入侵国外摄像头教程
•
【LUR】添加网站本地背景音乐各种播放模式
•
【LUR】非常实用!使用BootStrap实现布局~
•
【解忧】最全的JAVA知识汇总(附讲解和思维导图)
•
【DMT】教你们修改器如何播放音乐教程
•
哔哩哔哩关注用户协议软件,支持多线程,引流软件
•
SMTP邮件群发软件,支持163邮箱,谷歌邮箱,126邮箱等等...,QQ邮箱,
回复
使用道具
举报
返回列表
发帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
快速回复
返回顶部
返回列表