android 线程里的变量没有变化_一切从android的handler说起(二)

本文深入探讨Android中线程变量的管理,通过Handler和ThreadLocal的结合,确保每个线程只有一个Looper,并解释ThreadLocal如何利用Thread对象作为键来存储线程局部变量,确保线程间数据隔离。同时,文章介绍了ThreadLocal的应用场景及其与锁的区别,并提及Message Queue的线程唯一性。
摘要由CSDN通过智能技术生成

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

8db723277f56ca96e32e9cd2f08a4bf3.png

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

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

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

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

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

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

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

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

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

88b040409877481a0e5b6645c3536f9c.png

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

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

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

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

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

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

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

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

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

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

未完待续...

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

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


1d7fbb158710d0bae1f0c828d2687b1f.png

欢迎转发,关注公众号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值