AsyncTask和線程池

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

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

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

AsyncTask線程池

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

  • THREAD_POOL_EXECUTOR:多個任務(wù)在線程池中異步并發(fā)執(zhí)行
  • SERIAL_EXECUTOR:多個線程按串行同步方式執(zhí)行

THREAD_POOL_EXECUTOR 異步線程池

構(gòu)造方法:

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

其中:

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

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



從AsyncTask默認構(gòu)造的THREAD_POOL_EXECUTOR可以看出,AsyncTask最大支持的緩沖任務(wù)隊列是128個。

SERIAL_EXECUTOR 串行線程池

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


執(zhí)行AsyncTask的兩個方法

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

AsyncTask優(yōu)點

  • 內(nèi)部采用了線程池機制,可以有效的管理線程
  • 可以自定義線程池,實現(xiàn)多個線程按順序同步執(zhí)行、異步并發(fā)執(zhí)行
  • 提供了回調(diào)方法,后臺任務(wù)執(zhí)行完畢后會返回需要的數(shù)據(jù),拿到數(shù)據(jù)后可以直接更新UI控件

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

參考資料

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

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

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

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