一个线程如何保证只有一个Loop?
tip(什么是threadlocal? 是一块线程的内部的存储类,可以指定线程内存数据。这块数据只能线程内使用 )实际是它的静态内部类ThreadLocalMap为每个Thread维护了一个数组 下标是ThreadLocal分配的 value存储对应的值。为了保证只有一个值,则需要判断这个map对应key的vaalue是否为空,空就不设置。
Loop的构造器是private的,通过Loop里面的prepare方法初始化的。prepare方法里用到了threadlocal判断是否是空如果是空才setlooperf否则不设置这样保持只有一个loop。Thread ==》threadlocalmap(存储空间<唯一的threadlocal,value就是loop>==》这个流程保证了一个线程只有一个Loop。同时也创建了一个messagequeue.
一个线程有几个Handler?
可以随便new,但是只有一个loop和messagequeue
Handler为什么会出现内存泄漏?
内部类持有外部类的应用 我们将消息 发送,入队列中。masg 持有 handler handler 持有 activity 。消息在队列中有延时activity销毁会出现内存泄漏。
如果handler为内部类(非静态内部类),那么会持有外部类的实例 若在handler.sendMessage的时候,activity finish掉了,那么此时activity将无法得到释放
如果申明handler为静态内部类,则不会含有外部类的引用, 但是需要在handler中更新UI(注意此时handler为static),则需要引入一个activity引用, 显然必须是弱引用,否则会导致和上面一样的结果
使用activity弱引用 之所以使用弱引用,是因为handler为static,使用activity的弱引用来访问activity对象内的成员
主线程没消息的时候怎么处理?子线程呢?
主线程会一直循环 ,因为Loop是我们ActivityThread 创建的不用管理关闭方法
消息睡眠和唤醒机制
生产者-消费者设计模式:
多线程: 10个事件,11
两个方面的阻塞?
1) message 不到时间 ,自动唤醒
2) messageQueue为空,无限等待直到添加消息唤醒
子线程调用 quit: 唤醒线程-》 messagequeue -》null -》 退出loop
既然可以多个Handler往MessageQueue中添加数据(发送消息的handler可能处于不同线程)那么它内部是如何确保线程安全的?
锁 synchronized:内置锁 可重入锁 外部锁
messagequeue 的 添加 enqueue 和 next 取出 和退出 quit 被锁,对象里面的所有的函数,代码块,都会受限
锁:面试,锁
类 对象
MessageQueue 111= new messagequeue();
111. enqueueMessage
MessageQueue 222= new messagequeue();
222.enqueueMessage
222.next(222对象被锁只有调用完之后才能使用)
1个线程只有一个可以操作MessageQueue 的地方
线程池是如何实现先进先出的?
先进通过排序算法 插入维护时间先后顺序 ,然后从最前面取出
Handler运行流程?
子线程
handler-》sendMessage -> messasgeQueue.enqueueMessage //消息队列队列的插入节点(是一个容器相当于内存不是属于哪个线程)
looper.loop()-> messasgeQueue.next()-》handler.dispatchMessage()->handler.handleMessage()
主线程
Message,在动的过程,内存
new Messaage() obtain()
我们使用Message是如何创建的?
message 从队列中取出后没有销毁,而是将里面的参数都制空放到messagepoll里面,方便以后使用。避免频繁创造对象导致内存抖动。也叫享元设计 内存复用
Loop的死循环为什么不会导致应用的卡死?
Anr:5s内没处理玩 Activity Msg ——》5s——》handler---------》发消息anr提醒
而msg block 没消息处理 休眠 线程没事做放出Cpu
什么是消息的同步屏故障?
消息是根据执行时间进行先后排序,然后消息是保存在队列中,因而消息只能从队列的队头取出来。那么问题来了!需要紧急处理的消息怎么办
异步消息:刷新UI16ms左右 刷新UI:否则闪屏
异步消息: 立刻执行 messageQueue.postSyncBarrier() -》立刻执行,不能等别的消息 最后remove
在循环去消息的时候,判断targt==null 满足说明有同步消息
同步:正常消息
如何在子线程收消息 在主线程发消息?
HandlerThread 实现Loop.prepare 和loop.loop 有个GetLoop方法获取到loop 并且线程安全
解决这个有可能得异步问题
面试: 多线程得锁
wait();会释放synchronized锁
synchronized()
nofityall() 不会释放sychronized 会唤醒wait
最简单得: okhttp glide,
IntentService
应用:
service:? 处理后台耗时任务
new Thread
service 后台
handler源码?源码有什么用
处理完》 service 自动停止:内存释放
同一个线程-》1 2 3 4 都执行完才算成功: 对线程的控制么 可以用多个线程来处理,一个线程处理完——————》下一个 ——》下一个
IntentSevice就可以完成这个工作 而且能够很好地管理线程,保证只有一个子线程处理工作而且是一个一个任务完成的有条不紊。HandlerThread 保证一个loop 一个线程 队列保证顺序
到底还有别的地方用么?
很多地方有这么用
fragment什么生命周期管理