摘要:當(dāng)然,如果你的核心數(shù)夠多,到個(gè)線程的并行度不滿足的話,也可以自定義一個(gè)線程池來執(zhí)行,不過這樣的話,要注意自己維護(hù)這個(gè)線程池的初始化,釋放等等操作了。
事情起源于一個(gè)bug排查,一個(gè)AsyncTask的子類,執(zhí)行的時(shí)候發(fā)現(xiàn)onPreExecute方法執(zhí)行了,doInBackground卻遲遲沒有被調(diào)用。
懂AsyncTask一些表面原理的都知道,onPreExecute方法是在主線程執(zhí)行,doInBackground方法是在后臺(tái)線程執(zhí)行,所以很明顯是后臺(tái)線程被卡住了執(zhí)行不了,所以這就涉及到AsyncTask的原理問題了,查看出現(xiàn)bug的版本——Android 6.0源碼可以知道,AsyncTask里面維護(hù)著兩個(gè)線程池,THREAD_POOL_EXECUTOR和SERIAL_EXECUTOR,其中SERIAL_EXECUTOR是默認(rèn)的線程池:
如果用AsyncTask.execute(params...)方法來執(zhí)行任務(wù),就會(huì)用到默認(rèn)的線程池,即SERIAL_EXECUTOR;可以看出SERIAL_EXECUTOR會(huì)讓所有的線程串行執(zhí)行:
而且由于SERIAL_EXECUTOR被聲明為static,所以,同一個(gè)進(jìn)程里的AsyncTask都會(huì)共享這個(gè)線程池,這就意味著,在同一個(gè)進(jìn)程里,前面的線程不結(jié)束,后面的線程就會(huì)被掛起,這正是我遇到的情況。
接下來排查所有用AsyncTask.execute方法來執(zhí)行任務(wù)的情況,終于找到了一個(gè)不合理的調(diào)用————在doInBackground里請(qǐng)求網(wǎng)絡(luò),一直死等response,而沒有超時(shí)釋放。修復(fù)了這種情況,問題就迎刃而解了。
除了這種解決前面線程不合理設(shè)計(jì)的辦法,還有沒有別的解決方式呢,因?yàn)橛袝r(shí)候,我們的設(shè)計(jì)確實(shí)是讓后臺(tái)線程死循環(huán),不跳出的。
當(dāng)然有的,在AsyncTask設(shè)計(jì)上就考慮到了,前面說到AsyncTask里面還有一個(gè)線程池THREAD_POOL_EXECUTOR,從它的初始化參數(shù)可以看出,這是一個(gè)支持2到4個(gè)線程并行的線程池:
所以,使用AsyncTask執(zhí)行任務(wù)的時(shí)候,請(qǐng)使用AsyncTask.executeOnExecutor(THREAD_POOL_EXECUTOR)來讓你的任務(wù)跑在并行的線程池上,避免出現(xiàn)并前面線程阻塞的情況。當(dāng)然,如果你的CPU核心數(shù)夠多,2到4個(gè)線程的并行度不滿足的話,也可以自定義一個(gè)線程池來執(zhí)行AsyncTask,不過這樣的話,要注意自己維護(hù)這個(gè)線程池的初始化,釋放等等操作了。
PS:AsyncTask是不是一開始就是被設(shè)計(jì)成這樣的呢?筆者調(diào)研了一下,其實(shí)Android 1.5剛開始引入AsyncTask的時(shí)候,execute方法確實(shí)是串行執(zhí)行的,類定義里面只有SERIAL_EXECUTOR線程池;到1.6版本時(shí),改用并行線程池THREAD_POOL_EXECUTOR,再到3.0版本至今,就成了上面說的模樣————定義兩個(gè)線程池,但是默認(rèn)用串行池。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/67602.html
摘要:異步任務(wù)的構(gòu)造方法主要用于初始化線程池先關(guān)的成員變量創(chuàng)建一個(gè)新的異步任務(wù)。所以,我們是必須確保在銷毀活動(dòng)之前取消任務(wù)。 目錄介紹 01.先看下AsyncTask用法 02.AsyncTask源碼深入分析 2.1 構(gòu)造方法源碼分析 2.2 看execute(Params... params)方法 2.3 mWorker和mFuture的創(chuàng)建過程 03.異步機(jī)制的實(shí)現(xiàn) 04.不同...
摘要:相關(guān)環(huán)境由于是一個(gè)幾年前的項(xiàng)目,所以使用的是這樣的。一些小提示本次優(yōu)化筆記,并不會(huì)有什么文件的展示。將異步改為了串行,喪失了作為異步事件流的優(yōu)勢(shì)。 這兩天針對(duì)一個(gè)Node項(xiàng)目進(jìn)行了一波代碼層面的優(yōu)化,從響應(yīng)時(shí)間上看,是一次很顯著的提升。 一個(gè)純粹給客戶端提供接口的服務(wù),沒有涉及到頁面渲染相關(guān)。 背景 首先這個(gè)項(xiàng)目是一個(gè)幾年前的項(xiàng)目了,期間一直在新增需求,導(dǎo)致代碼邏輯變得也比較復(fù)雜,接...
閱讀 2881·2021-09-28 09:36
閱讀 3608·2021-09-27 13:59
閱讀 2484·2021-08-31 09:44
閱讀 2278·2019-08-30 15:54
閱讀 2352·2019-08-30 15:44
閱讀 1180·2019-08-30 13:45
閱讀 1222·2019-08-29 18:38
閱讀 1206·2019-08-29 18:37