「性能優(yōu)化3.0」Android線程調(diào)度&異步方式匯總

線程調(diào)度與線程調(diào)度模型

任意時(shí)刻,只有一個(gè)線程占用 CPU,處于運(yùn)行狀態(tài)。而多線程并發(fā)執(zhí)行就是輪流獲取 CPU 執(zhí)行權(quán)。

  • 分時(shí)調(diào)用模型

輪流獲取 CPU 執(zhí)行權(quán),均分 CPU 執(zhí)行時(shí)間。

  • 搶占式調(diào)度模型

優(yōu)先級(jí)高的線程優(yōu)先獲取 CPU 執(zhí)行權(quán),這也是 JVM 采用的線程調(diào)度模型。

nice value

nice value 表示進(jìn)程的優(yōu)先級(jí),nice value 越小,線程優(yōu)先級(jí)越高。這個(gè)值是在 Process 類(lèi)中定義的。默認(rèn)的 THREAD_PRIORITY_DEFAULT,值為0.

nice value

下面來(lái)關(guān)注一下哪些異步框架如何設(shè)置這些 nice value 。

  • HanlderThread
HandlerThread 默認(rèn)優(yōu)先級(jí)
  • AsyncTask
AsyncTask默認(rèn)優(yōu)先級(jí)

cgroup(control group)

借鑒了 Linux ,它是更嚴(yán)格的群組調(diào)度策略,保證前臺(tái)進(jìn)程獲取更多的 CPU。那些手動(dòng)設(shè)置優(yōu)先級(jí)比較低的線程或者不在前臺(tái)運(yùn)行的應(yīng)用程序的線程會(huì)被放入后臺(tái) group ,后臺(tái) group 也是可以被 CPU 調(diào)度運(yùn)行,只是獲取 CPU 執(zhí)行權(quán)的概率會(huì)比較低,這樣就不會(huì)影響到前臺(tái)group 的運(yùn)行。

所以說(shuō)需要設(shè)置要對(duì)應(yīng)的 nice value ,因?yàn)樵撝禃?huì)影響到線程獲取 CPU 執(zhí)行權(quán)的概率。

CPU 密集型與 IO 密集型

CPU 密集型

大量的計(jì)算,消耗CPU資源,例如視頻進(jìn)行高清解碼,為了重復(fù)利用 CPU 資源,應(yīng)該將線程數(shù)量設(shè)置為CPU的核心數(shù)+1。

IO 密集型

網(wǎng)絡(luò)、磁盤(pán)IO,這時(shí)線程大多數(shù)時(shí)間是阻塞等待 IO 完成的,因?yàn)?IO 操作是不占用 CPU 的,為了提高線程的利用率,盡可能的創(chuàng)建更多的任務(wù),這樣 CPU 的效率就越高,但是這個(gè)數(shù)量是有限制的,不能無(wú)限制大,線程數(shù) = 2*CPU 核心數(shù)。

多線程優(yōu)化的注意點(diǎn)

  • 線程具有繼承性

在 UI 線程中如果創(chuàng)建子線程,那么該線程的優(yōu)先級(jí)是和 UI 線程一樣的,因此 UI 線程獲取到 CPU 執(zhí)行權(quán)的機(jī)率肯定會(huì)漸低。

  • 根據(jù)任務(wù)的性質(zhì)來(lái)設(shè)置線程數(shù)量,具體參考上面的 CPU 密集型和 IO 密集型的知識(shí)點(diǎn)。

Android 的異步方式

  • 直接使用 Thread

這種方式是最簡(jiǎn)單的,但是也是最不推薦的方式,因?yàn)轭l繁的創(chuàng)建和銷(xiāo)毀,增大了系統(tǒng)資源的開(kāi)銷(xiāo),并且通過(guò)這種方式創(chuàng)建的線程無(wú)法得到控制,也不能被復(fù)用。

  • HandlerThread

內(nèi)部結(jié)合了 Handler 和 Thread ,特點(diǎn)就是串行執(zhí)行每一個(gè)任務(wù)。

  • IntentService

內(nèi)部是使用 HandlerThread ,因此具備 HandlerThread 的特點(diǎn),因?yàn)槔^承至 Service ,因此優(yōu)先級(jí)比較高,不容易被系統(tǒng)殺死,它就相當(dāng)于一個(gè)可以跑異步任務(wù)的 service 。

  • AsyncTask

內(nèi)部提供了線程池,在異步任務(wù)執(zhí)行前,執(zhí)行中,執(zhí)行完成都會(huì)相應(yīng)的回調(diào)。

  • 線程池

Executors 工具類(lèi)提供了很多系統(tǒng)內(nèi)置好的線程池,當(dāng)然也可以通過(guò)自己去配置線程池的參數(shù)。

  • RxJava

可以通過(guò)任務(wù)的類(lèi)型,選擇 CPU 密集型的還是 IO 密集型的線程池去執(zhí)行。

參考

https://droidyue.com/blog/2015/09/05/android-process-and-thread-schedule-nice/

本文是筆者學(xué)習(xí)之后的總結(jié),方便日后查看學(xué)習(xí),有任何不對(duì)的地方請(qǐng)指正。

記錄于 2019年4月16號(hào)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容