一切从android的handler说起(二)之threadLocal

本文从ThreadLocal的角度探讨Android中Looper的唯一性,解释ThreadLocal如何保证每个线程仅有一个Looper,并分析其在多线程场景下的应用与与锁的区别。同时,文章提及Message Queue的线程唯一性及其与Looper的关系。

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

 阅读本文大概需要2分钟。

 

 

看小张有些受惊,我打算换个新的角度。

 

继续问道:刚才说到每个线程只能有一个唯一的looper,你知道android是怎么保证这一点的吗?

小张眼睛躲避着我的视线,模糊的回答道:我好像记得有个threadLocal和这个有关。

 

为了给小张一点鼓励,我说道:没错,你说对了,就是它!

小张感觉打了一针强心剂。

 

我继续问道:那threadLocal是怎么做到的呢,你能说具体一点吗?

小张:我记得threadLocal里面的核心就是一个hashmap,用来保证的。

 

我来了兴趣,继续问:那这个hashmap里的key和value分别是什么能达到这个目的?

小张开始支支吾吾...过了一会儿说道:value里存的是looper对象,key存的是...

 

                                                       

 

看到小张期待求助的眼神,我继续提示道:你想想key用什么能够保证线程和looper的唯一映射?肯定是唯一代表线程的东西,对吧?

小张:哦,要是我来设计,会用thread本身来当key来保证这一点。

 

我看小张还是不很确定,就肯定的说道:没错,threadlocal正是用的thread对象本身来当key[注1],这样每次在thread里创建一个looper时,系统都会先去全局的threadLocal里的hashmap看看对应的线程里是否已经存了looper,如果没有,就说明这个线程还没有创建过looper,就正常创建,然后存进hashmap里。如果已经有了,就会报错。如此一来,每个线程就像在自己的环境里保存本地变量一样,互不干扰,这也就是Local的意思。

 

为了考察小张的学习能力,我又问道:那你觉得threadlocal一般能够使用在哪些场景呢?它和锁在使用场景上有啥区别啊?

小张这次没有让我失望,回答道:当开发过程中需要一个全局变量能够在多线程场景中使用,而且互不干扰,可以定义一个threadlocal即可,而无需为每个线程定义一个全局静态变量,使用起来非常方便。锁就不一样了,它是为了保证一个变量在不同的线程之间共享而存在的控制手段。简而言之,一个是线程独立,一个是线程共享,场景不同。

 

听到这个回答我内心是非常赞赏的,但是作为一名合格的面试官,必须不露声色。

继而又问:既然looper是通过threadlocal保证了唯一性,那message queue[注2]唯一性又是如何保证的呢?

小张这次笑了:这个简单,由于message queue是looper里的一个属性,looper是线程唯一的,所以message queue也是线程唯一的。

 

我点了点头,对小张一轮战绩表示了肯定。

小张感叹道:没想到面试还能学习到这么多知识啊...

 

未完待续...

 

[注1]:真正的源码实现要比这个稍微复杂一些,使用的是ThreadLocalMap,但大体都是map的思想,具体参见源码。

[注2]:很多同学都读做Queen(皇后),我内心是崩溃的,正确发音应该是字母Q,读对了在我这里面试都会打高一分。

 



有热爱Android技术的同学,欢迎加 QQ群 726464410,或者扫描QQ群二维码 和 微信公众号二维码。用诙谐的方式学习Android硬核知识点。

                       

                                                                              欢迎转发,关注公众号
 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值