IntentService、HandlerThread与ThreadLoccal、ThreadLocalMap

1、IntentService

2、从上图看出是个服务,所以看下onCreate方法,初始化了一个HandlerThread对象,以及一个Handler,注意Handler传入的Looper对象是HandlerThread对象

3、onStart方法 ,注意msg属性的赋值

 

4、接下来看下onHandleIntent执行时所在的线程

上面说了Handler传入的是HandlerThread中的Looper,那么HandlerThread是什么 呢?

5、HandlerThread首先是一个线程

6、之前有说过开启线程的方法之一就是继承Thread,新生成对象后调用start,会运行run方法

7、IntentService赋值的looper是什么呢?,可以看出就是mLooper

8、为什么调用wait,因为虽然上面我们调用了start但是线程此时只是就绪状态,而不是运行状态,只有拿到CPU使用权才可会运行run方法,这也是为什么HandlerThread要调用notifyAll的原因。不得不说每行代码都是宝啊

9、IntentService中的Handler是HandlerThread中的looper,那么当消息队列中的消息执行时运行的线程就是开启的HandlerThread线程。为什么呢?

我们看下Loop.prepare();做了什么操作?

从上面代码看出获取线程中的ThreadLocalMap对象,如果为空就初始化,并放入第一个值

而存入的key就是当前的ThreadLocal对象,value就是Looper

10、再来看下Looper.loop();方法

从上面代码看出获取当前线程的ThreadLocalMap对象,在获得以threadLocal作为key的entry然后获取value

就是刚才存入的looper对象,在获取looper中的消息队列然后在获取msg最终执行了 msg中持有的target对象,就是IntentService中的Handler。具体请看Handler源码解析。所以说IntentService中的抽象方法是运行在子线程的

11、ThreadLocalMap是实现的我们常见的Map吗?看代码就一目了然

事实上他不仅没有实现Map,还和我们常见的Map在Hash冲突和数据结构有很大差异,首先它的key值总是ThreadLocal,在looper中ThreadLocal是静态变量(保证了一个线程一个looper),既然key类型一样,自然没有必要像Map那样处理Hash

虽然每次生成新的对线下个对象的hash值会加上斐波拉契数列,但还是有可能产生hash碰撞处理和获取方法下面贴出代码

另外特殊的是集合中存储的对象其key是弱引用

而对于value的内存泄漏是每次set或get时未能成功命中目标节点,发现key为null时对该节点删除从而释放value

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值