android线程间通信的本质和原理

641 阅读2分钟

线程间的交互

  1. 一个线程启动别的线程:new Thread().start()Executor.execute()
  2. 一个线程终结另一个线程
    • Thread.stop()
    • Thread.interrupt():温和式终结:不立即、不强制
      1. Interrupt()isInterrupted():检查(和重置)中断状态
      2. InterruptedException:如果在线程等待时中断,或者在中断状态等待,直接结束等待过程
  3. Object.wait()和Object.notify()/notifyAll()
    • 在未达到目标时wait()
    • 用while循环检查
    • 设置完成后notifyAll()
    • wait()和notify()/notifyAll()都需要放在同步代码块里
  4. Thread.join():让另一个线程插在自己前面
  5. Threa.yield():暂时让出自己的时间片给同优先级的线程

Android的Handler机制

  1. 本质:在某个指定的运行中的线程上执行代码
  2. 思路:在接受任务的线程上执行循环判断
  3. 基本实现:
    • Thread里while循环检查
    • 加上Looper(优势在于自定义Thread的代码可以少些很多)
    • 再加上Handler(优势在于功能分拆,而且可以有多个Handler)
  4. java的Handler机制:
    • HandlerThread:具体的线程
    • Lopper:负责循环、条件判断和任务执行
    • Handler:负责任务的定制和线程间传递
  5. AsyncTask:
    • AsyncTask的内存泄漏
      • 众所周知的原因:AsyncTask持有外部Activity的引用
      • 没提到的原因:执行中的线程不会被系统回收
      • java回收策略:没有被GC Root直接或间接持有引用的对象,会被回收 GC Root:
        1. 运行中的线程
        2. 静态对象
        3. 来自native code中的引用
      • 所以AsyncTask的内存泄漏其他的线程方案都会有(Thread、Executor、HandlerThread)一样都有,不能认为AsyncTask比别的方案更危险
      • 就算是使用AsyncTask,只要任务的时间不长,就没有必要做纺织内存泄漏的处理

Service和IntentService

  1. Service:后台任务的活动空间。使用场景:音乐播放器等。
  2. IntentService:执行单个任务后自动关闭的Service ###Executor、AsyncTask、HandlerThead、IntentService的选择 原则:那个简单用哪个
  3. 能用Executor就用Executor
  4. 需要用到后台线程推送任务到UI线程时,再考虑AsyncTask或者Handler
  5. 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(); 
}