线程间的交互
- 一个线程启动别的线程:
new Thread().start()
、Executor.execute()
等
- 一个线程终结另一个线程
- Thread.stop()
- Thread.interrupt():温和式终结:不立即、不强制
Interrupt()
和isInterrupted()
:检查(和重置)中断状态
InterruptedException
:如果在线程等待时中断,或者在中断状态等待,直接结束等待过程
- Object.wait()和Object.notify()/notifyAll()
- 在未达到目标时wait()
- 用while循环检查
- 设置完成后notifyAll()
- wait()和notify()/notifyAll()都需要放在同步代码块里
- Thread.join():让另一个线程插在自己前面
- Threa.yield():暂时让出自己的时间片给同优先级的线程
Android的Handler机制
- 本质:在某个指定的运行中的线程上执行代码
- 思路:在接受任务的线程上执行循环判断
- 基本实现:
- Thread里while循环检查
- 加上Looper(优势在于自定义Thread的代码可以少些很多)
- 再加上Handler(优势在于功能分拆,而且可以有多个Handler)
- java的Handler机制:
- HandlerThread:具体的线程
- Lopper:负责循环、条件判断和任务执行
- Handler:负责任务的定制和线程间传递
- AsyncTask:
- AsyncTask的内存泄漏
- 众所周知的原因:AsyncTask持有外部Activity的引用
- 没提到的原因:执行中的线程不会被系统回收
- java回收策略:没有被GC Root直接或间接持有引用的对象,会被回收
GC Root:
- 运行中的线程
- 静态对象
- 来自native code中的引用
- 所以AsyncTask的内存泄漏其他的线程方案都会有(Thread、Executor、HandlerThread)一样都有,不能认为AsyncTask比别的方案更危险
- 就算是使用AsyncTask,只要任务的时间不长,就没有必要做纺织内存泄漏的处理
Service和IntentService
- Service:后台任务的活动空间。使用场景:音乐播放器等。
- IntentService:执行单个任务后自动关闭的Service
###Executor、AsyncTask、HandlerThead、IntentService的选择
原则:那个简单用哪个
- 能用Executor就用Executor
- 需要用到后台线程推送任务到UI线程时,再考虑AsyncTask或者Handler
- HandlerThread的使用场景:原本它设计的使用场景是在已经运行的指定线程上执行代码,但现实开发中,除了主线程外,几乎没有这种需求,因为HandlerThread和Executor相比在实际应用中并没有什么优势,反而用起来会麻烦些。想用谁就用谁
4.IntentService:首先,它是一个Service;另外,它在处理线程本身,没有比Executor有任何优势
###关于Executor和HandlerThread的关闭
如果在界面组件里创建Executor或者HandlerThread,在关闭时关闭ExeCutor和HandlerThread。
@Override
protected void onDestroy() {
super.onDestroy();
executor.shutdown();
}
@Override
protected void onDestroy() {
super.onDestroy();
// 这个其实就是停⽌ Looper 的循环
handlerThread.quit();
}