The Importance of Thread Priorit
上次翻译的是第五季第七集,这次是第九集,中间还差个第八集,因为某些原因打算后面在翻译,这次呢讲的是线程的优先级对于性能的影响,接下来就让我们进入主题吧。
本期视频地址:
视频开头.pnghttps://www.youtube.com/watch?v=NwFXVsM15Co&index=9&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE
视频刚开头就是一段阅读读者来信的内容,信的内容是这样的:“你个秃顶,老子看了你的线程方面的视频,自己创建了 100 个线程去完成任务,使我的 App 变慢了。你真是个糟糕的人,你应该感到愧疚!”,当然这是我娱乐的翻译。
技术上,你可以在你的 App 中创建上百个线程,但正如你猜的,这或许不是性能上最佳的注意。
将太多线程填充到没有足够 CPU 的机器上是个老问题了,几十年了,线程调度器已经通过各种度量方式,来确定 CPU 此刻应该执行哪个线程来解决问题。
多线程同时工作.jpg基本上,每个线程都被分配来了一个优先级。
调度器,之后给出了更重要的线程偏好,平衡了最终真的需要执行的任务。
现在,优先级有以下几种分配方式。
首先,Android 分配线程的优先级基于 App 中 Activity 的生命周期状态。
App 中可见的 Activity 被分配到了前台组,其余的被分配到了后台组。
前台组与后台组的时间分配.png在前台组的线程在设备中获得了了大概 90% ~ 95% 总执行时间,而处在后台组的线程则只占了 5% ~ 10%,哪个有道理呢?
我的意思是,在屏幕上可见的应用比那些不可见的应用获得更多的处理器分配。
其次,重要的是注意当线程被创建时,默认的赋予了它,与其他被创建的线程相同的优先级。
线程们都有相同的优先级.png因此,它们在相同的条件下竞争处理器时间的分配。
So,如果你的主线程创建了 20 个其他高优先级的工作线程,它们都将竞争同样的 CPU 资源,这几乎毁了你在 16 ms 内完成所有 UI 线程工作的机会。
它们也会和主线程竞争资源.png为了修复这个问题,你应该明确的为你应用中创建的任何线程都设置线程的优先级。
这帮助系统在相同的控制组中去调度竞争线程。
在 Android 中可以方便的 Process.setThreadPriority() 这个 API 来设置线程的优先级。
Process.setThreadPriority().png现在,令人疑惑的是,这个函数取值范围为 -20 ~ 20 的正整数(官方文档写着 -20 ~ 19),其中较低的值表示较高的优先级。
setThreadPriority(int).png技术上,这些数字实际上应该表示这个线程在分享时间方面的友好程度,所以,负数意味着更敌对的时间分享(更不愿分享)。
但无所谓。
使之更清楚一点,Android 提供了一些值得使用值。
Process 类中自带的一些常量.jpg这些值被定义在 android.os.Process 中,并且可以当做基础状态。
默认的,当然是你的线程通常给出的。
在此之上,这里还有一对可以量化的值,用来帮助你增加或减少优先级,以获得更细微的控制。
更细微的控制值.png例如,UI 线程永远被分配默认的优先级,任何其他的生成的线程也将被赋予同样的值。
但实际上,工作线程应该用较低的优先级,你可以通过添加 THREAD_PRIORITY_LESS_FAVORABLE 来设置,毕竟值越大优先级越低。
设置工作线程的优先级.png这种方法可以让你生成的线程可能相比其他线程拥有较多或者较少的重要性。
事实上,自己设置这些优先级可能很麻烦。
这就是为什么有了 AsyncTask 和 IntentService 替我们做了这些设置,所以,你不必处理这些。
系统提供好了这些类.png但如果你使用原始线程,那么当然你必须自己设置优先级,所以请留意下,性能上可能出现的奇怪的事情。
翻译有些不太好,有些句子还是理解不好,有些句子读起来很拗口,我会尽量完善自己英文水平,这就是本期视频的内容,有兴趣的话你可以自己去 YouTube 上亲自看看。
我之前看过 AsyncTask 但是并没有注意到这一点,而我在这个系列视频中也学到了不少关于性能上注意点,毕竟官方啊。
AsyncTask 源码.png