讀書筆記之Android線程和線程池

本文是閱讀安卓開發(fā)藝術探索一書第十一章的筆記和延伸感想

概述

Android中扮演線程角色的有:Thread,AsyncTask,IntentService,HanderThread...當線程數(shù)大于CPU核數(shù)時,需要通過時間片輪轉方式來調度線程。

AsyncTask

封裝了Thread和Handler的異步任務,提供/重寫四個核心方法

  • onPreExecute()
  • doInBackground()
  • onProgressUpdate()
  • onPostExecute()

當異步任務被取消時,onCancelled()被調用,此時onPostExecute不會被調用,從AsycTask源碼內部類InternalHandler可以得出此結論。

使用注意事項

  1. AsyncTask類必須在主線程中加載
  2. AsyncTask對象必須在主線程中創(chuàng)建
  3. 一個AsyncTask對象職能執(zhí)行一次,即只調用一次execute方法
  4. AsyncTask內部提供兩種線程池,當調用execute方法是串行執(zhí)行任務,當調用executeOnExecutor方法是并行執(zhí)行任務

HandlerThread

把Looper的創(chuàng)建(創(chuàng)建Looper時,會創(chuàng)建對應的MessageQueue)和開啟消息循環(huán)的操作做了封裝的線程類,因此可以很方便的和Handler的配合使用。

IntentService

封裝了HandlerThread和Handler,當任務執(zhí)行完畢后IntentService會自動退出。后臺服務優(yōu)先級高于后臺線程,能盡量保證任務執(zhí)行。

IntentService的OnHandleIntent方法是一個抽象的方法,它需要在子類中實現(xiàn),它的作用是從Intent參數(shù)中區(qū)分具體的任務并執(zhí)行這些任務。

每啟動一次IntentService(調用startService方法),就會執(zhí)行一次onHandlerIntent()。如果目前存在多個后臺任務,那么當onHandleIntent方法執(zhí)行完最后一個任務時,stopSelf(int startId)才會直接停止服務。

線程池

線程池的優(yōu)點

  • 重用線程池中的線程,避免因為線程的創(chuàng)建和銷毀所帶來的性能開銷(緩存的意義)
  • 能有效控制線程池的最大并發(fā)數(shù),避免大量的線程之間因互相搶占系統(tǒng)資源二導致阻塞現(xiàn)象。
  • 扮演線程管理者,提供簡單的管理和定時/循環(huán)執(zhí)行任務

ThreadPoolExecutor相關概念

  • corePoolSize 核心線程數(shù)
  • maxiMumPoolSize 最大線程數(shù)
  • keepAliveTime 非核心線程超時時間
  • BlockingQueue 任務隊列,存放線程池需要執(zhí)行的任務
  • ThreadFactory 線程工廠
  • AllowCoreThreadTimeOut 該屬性設置為true時,表示核心線程閑置超過超時時長,核心線程會被回收;false,則不會被回收,在線程池中一直存活。

ThreadPoolExecutor默認工作策略

  1. 如果線程池中的線程數(shù)量未達到核心線程數(shù),直接新建一個核心線程
  2. 如果線程池中的線程數(shù)量已經(jīng)達到或者超過核心線程數(shù)量,任務被插入到任務列表等待執(zhí)行
  3. 如果步驟2中無法將任務插入到任務列表中(任務列表已滿),此時如果線程數(shù)量未達到線程池最大線程數(shù),那么會新建一個非核心線程執(zhí)行任務
  4. 步驟3中線程池已達到最大線程數(shù)(任務列表也滿了),那么久拒絕執(zhí)行此任務,ThreadPoolExecutor調用RejectedExecutionHandler的rejectedExecution方法來通知調用者。

另外,這期間,當非核心線閑置超過超時時長,非核心線程會被回收。

ThreadPoolExecutor線程池的分類

FixedThreadPool

概述

這是核心線程數(shù)固定值,沒有非核心線程,沒有超時時長的回收,任務隊列為LinkedBlockingQueue,隊列大小無限大的ThreadPoolExecutor。

特點

因此該線程池能夠更快的響應外界請求

CacheThreadPool

概述

這是沒有核心線程,非核心線程數(shù)為Integer.MAX_VALUE(相當于無限大),超時時長為60秒,任務隊列為SynchronousQueue(相當于空集合)的ThreadPoolExecutor

特點

合適執(zhí)行大量的耗時較少的任務,當線程池沒有任務執(zhí)行,它幾乎不占用任何系統(tǒng)資源

ScheduledThreadPool

概述

這是有固定核心線程,非核心線程數(shù)不受限制,超時時長為0,任務隊列為DelayedWorkQueue的ThreadPoolExecutor

特點

適合執(zhí)行定時任務和具有固定周期的重復任務

SingleThreadExecutor

概述

這是只有一個核心線程,沒有非核心線程,沒有超時時長,任務隊列為LinkedBlockingQueue的ThreadPoolExecutor

特點

統(tǒng)一所有外界的任務到一個線程中,使得任務之間不需要處理線程同步的問題

小結

Android的線程和線程池,要想靈活得當?shù)氖褂茫€需要深入到相關類源代碼中,熟悉它們的邏輯。

把自己放入到特定場景中,會遇到什么問題,如果我來設計該怎么搭起這些工具類和架構,這樣多想想,就會感覺到各種套路,工程規(guī)范,設計模式在這里面起作用。這和我們平時做項目,封裝工作是相似的。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容