Android 中的线程调度

转载 2016年06月01日 19:26:17

本文概述了 Android 中的线程是如何调度的,并通过设置线程优先级来优化 APP-UI,保证 UI 线程优先级最高,从而提高用户体验。

线程调度听起来很学术,是操作系统中的概念:线程调度决定系统中不同线程运行,运行时间,何时运行。Android 中的线程调度很操作系统中的线程调度类似,主要使用 nice 和 cgroups 这两个变量来调度线程(本质上来说还是通过设置线程优先级,让 Linux 内核有依据的分配线程运行)。

Nice

我们这里的 Nice 与 Linux Kernel 的进程完全公平调度器(CFS)类似但是不一样(本质上,在创建线程的时候这个 Nice 值最终还是要传递给底层的,跟 Linux Kernel 中的 nice 是相同的)。Java 层的 Nice 在 Android 中是衡量线程优先级的重要参考指标;nice 值越大,线程优先级越低,反之越高;其中两个重要的线程优先级属性参数是,default 和 background , 对于 Android App,线程要做大量耗时工作,其优先级应该越低,否则系统有卡死的风险,反之,线程做的工作不多,应该设置其优先级较高。所以关于交互界面的线程(如 UI 线程等前台线程)会给 default 或更高的优先级,而后台线程(如执行 AsyncTask 的线程)的线程属性为 background 。

Nice这种特性可以让后台工作线程尽量少抢占前台线程的时间片(从OS来说),从而保证了用户界面的流畅性。实际上,仍有一种可能使 UI 卡死,例如有30个后台线程,但是只有1个 UI 进程,这30个后台线程可能占据了很大的计算资源,导致 UI 线程得不到及时运行,导致卡顿、掉帧;为了防止这种情况发生, Android 提出了 cgroups ,用来解决类似的问题。

Cgroups

为了解决上述问题,Android 将前台线程和后台线程分开运行,即利用Linux的cgroups 给前台线程建一个群,给后台线程建一个群,然后调度器在这两个群中跑,这样不管后台线程有多少,调度器总能照顾到前台线程的运行;所以用户体验得到了保证。

如何区分前台进程和后台进程的 cgroup?

Android 会自动将没有在前台进程 cgroup 运行的线程都放到后台进程的 cgroup 中,这就保证了不管开多少线程,只会将其分为两个 Group,前台 cgroup 和后台 cgroup;理论上,不管多少非前台线程运行,Android都能保证前台线程的运行。

设置线程属性

一般来说,Android API 将常用工作线程的优先级设置好了。例如,HandlerThread 的代码第30行,将线程优先级设置为Process.THREAD_PRIORITY_DEFAULT ; AsyncTask 代码第286行,将线程优先级设置为 Process.THREAD_PRIORITY_BACKGROUND 。再比如音乐播放的线程设置为 THREAD_PRIORITY_AUDIO ,Android API 将 常用情况都做了详细的分类

需要铭记于心的是,在 UI 主线程实例化的线程或线程池,都会继承 default 或foreground 属性(因为 UI 线程就是这个属性,子线程会继承父线程的属性),所以如果大量类似工作线程存在于前台进程的 cgroup 中话,可能会使 UI 变得非常不流畅。若是工作线程,建议在运行前通过Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND) 直接设置线程的属性。

1 new Thread(new Runnable() {
2   @Override
3   public void run() {
4     Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
5 
6     // ...
7   }
8 }).start();

Android线程调度机制

在Android Weekly上看到了一篇关于Android线程调度的文章,感觉挺不错的,试着将其翻译了一下,原文地址http://www.androiddesignpatterns.com/2014...
  • tianzhihen_star
  • tianzhihen_star
  • 2014年02月24日 15:27
  • 2348

[Android开发] RxJava2之路三 - 调度器Scheduler与线程控制

一、简介RxJava是一个异步的框架,使用Scheduler调度器进行很多操作,例如可以对线程进行控制。二、调度器种类常用的是 Schedulers.io()进行耗时操作、和AndroidSchedu...
  • niubitianping
  • niubitianping
  • 2017年02月09日 19:08
  • 3077

Android 中的线程调度

ZZ:http://stackvoid.com/Thread-Scheduling-in-Android/ 本文概述了 Android 中的线程是如何调度的,并通过设置线程优先级来优化 APP-UI...
  • wzzushx
  • wzzushx
  • 2015年06月15日 15:42
  • 494

Java - 请说出与线程同步以及线程调度相关的方法。

- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁; - sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedExcept...
  • chimomo
  • chimomo
  • 2017年10月26日 18:01
  • 357

Java线程: 线程调度

线程调度是Java多线程的核心,只有好的调度,才能充分发挥系统的性能,提高程序的执行效率。 一、休眠   休眠的目的是使线程让出CPU的最简单做法,线程休眠的时候,会将CPU交给其他线程,以便轮换...
  • arredando
  • arredando
  • 2017年08月04日 14:47
  • 316

浅析Linux线程调度

在Linux中,线程是由进程来实现,线程就是轻量级进程( lightweight process ),因此在Linux中,线程的调度是按照进程的调度方式来进行调度的,也就是说线程是调度单元。Linux...
  • MaximusZhou
  • MaximusZhou
  • 2014年12月20日 13:47
  • 7577

Java多线程的调度策略

在Java多线程环境中,为保证所有线程的执行能按照一定的规则执行,JVM实现了一个线程调度器,它定义了线程调度的策略,对于CPU运算的分配都进行了规定,按照这些特定的机制为多个线程分配CPU的使用权。...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2014年11月14日 20:22
  • 9024

进程线程调度

本文讲述的是linux和windows中的线程-进程调度基本原理。
  • gaoyazhao
  • gaoyazhao
  • 2016年06月15日 16:16
  • 2750

Java多线程调度方法

多线程
  • fumier
  • fumier
  • 2015年03月19日 20:41
  • 840

请说出与线程同步以及线程调度相关的方法

-wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁; -sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedExce...
  • u014136713
  • u014136713
  • 2016年05月16日 18:36
  • 2183
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 中的线程调度
举报原因:
原因补充:

(最多只允许输入30个字)