AsyncTask和線程池

在Android中,UI操作是線程不安全的,如果想要在子線程中進行UI操作,或者在主線程中進行耗時操作,則需要借助Android的異步消息處理機制。但我們需要開啟N個線程的時候,我們可以這樣做:

  1. 直接new N個Thread。這樣不利于線程管理,而且一般的Thread是沒有返回線程執行完畢的返回值的。
  2. 通過Handler與主線程通信。
  3. 異步任務管理類AsyncTask。Android 1.5版本后引入,結合Thread和Handler,非常靈活方便的從子線程切換到UI線程。

AsyncTask之所以如此強大,核心在于背后的線程池。下面我們就一起來了解一下AsyncTask與線程池的那點事。

AsyncTask線程池

AsyncTask中提供兩種線程池,但是其實在AsyncTask中只有一個線程池THREAD_POOL_EXECUTOR,只不過SERIAL_EXECUTOR實現了線程隊列,最終還是使用的THREAD_POOL_EXECUTOR:

  • THREAD_POOL_EXECUTOR:多個任務在線程池中異步并發執行
  • SERIAL_EXECUTOR:多個線程按串行同步方式執行

THREAD_POOL_EXECUTOR 異步線程池

構造方法:

public ThreadPoolExecutor(int corePoolSize, 
                    int maximumPoolSize, 
                    long keepAliveTime, 
                    TimeUnit unit, 
                    BlockingQueue<Runnable> workQueue, 
                    ThreadFactory threadFactory) { 
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); 
}

其中:

  • corePoolSize:線程池的核心運行線程數量
  • maximumPoolSize:線程池中可以創建的最大運行線程數量(包括核心運行線程)
  • keepAliveTime:當線程池線程數量超過corePoolSize時,多余的空余線程在緩沖隊列的存活時間,超時后將會被移除
  • unit:線程池維護線程所允許的空閑時間的單位,一般設置為秒
  • workQueue:線程池所使用的緩沖隊列,可以設置緩沖隊列容納的線程數量
  • threadFactory:線程工廠,用于創建線程。 當一個異步任務執行execute的時候將會通過該工廠new出一個thread

構造方法分析完畢,那么我們來看看AsyncTask中是什么樣的:



從AsyncTask默認構造的THREAD_POOL_EXECUTOR可以看出,AsyncTask最大支持的緩沖任務隊列是128個。

SERIAL_EXECUTOR 串行線程池

在ActivityThread中的有一段代碼,設置了當Android 版本api 小于12,也就是版本小于3.1時,默認是使用AsyncTask默認的異步線程池THREAD_POOL_EXECUTORAndroid 3.1 之后使用的是 SERIAL_EXECUTOR


執行AsyncTask的兩個方法

  • execute:使用的是AsyncTask默認的線程池。在3.1版本之前默認使用THREAD_POOL_EXECUTOR異步并發線程池,且系統默認最大并發執行5個線程,緩沖線程隊列最大128個。3.1版本之后系統,默認是使用SERIAL_EXECUTOR串行任務執行,異步任務將會是一個個順序執行。
  • executeOnExecutor 需要傳遞進去一個Executor,可以實現自定義線程池
Executor executor = new ThreadPoolExecutor(10,50,10, TimeUnit.SECONDS,new LinkedBlockingDeque<Runnable>(100));
new MyAsyncTask(progressBar).executeOnExecutor(executor);

AsyncTask優點

  • 內部采用了線程池機制,可以有效的管理線程
  • 可以自定義線程池,實現多個線程按順序同步執行、異步并發執行
  • 提供了回調方法,后臺任務執行完畢后會返回需要的數據,拿到數據后可以直接更新UI控件

當然,AsyncTask也是有缺點的,在3.1系統下默認使用AsyncTask線程池,不可以自定義線程池,如果線程不多,即使只有一個異步任務,還是會創建其他4個核心線程,非常耗能。

參考資料

AsyncTask
Android AsyncTask完全解析,帶你從源碼的角度徹底理解
Android AsyncTask(1)-使用方法和線程池解析

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

推薦閱讀更多精彩內容