AsyncTask基本使用懂a(chǎn)ndroid的都會,但還是有必要整理一下AsyncTask的實(shí)現(xiàn)原理揭斧,一方面是鞏固學(xué)習(xí)到的知識莱革,另一方面也是為了更深層次的理解AsyncTask的實(shí)現(xiàn)。因?yàn)槲以谝郧笆褂肁syncTask 過程的時候一知半解讹开,造成一些代碼的問
題盅视。
http://blog.csdn.net/lmj623565791/article/details/38614699
看過hongyang的分析AsyncTask的實(shí)現(xiàn)原理的這篇博客,我明白了3.0以前AsyncTask是支持多個線程同步執(zhí)行任務(wù)的旦万,但是3.0及3.0以后AsyncTask實(shí)際上是單線程執(zhí)行的闹击。 也就是說3.0以后我們使用不同的AsyncTask實(shí)例去執(zhí)行任務(wù),還是需要等待之前的任務(wù)執(zhí)行結(jié)束成艘,后續(xù)任務(wù)才能執(zhí)行赏半。
但是還是有個疑惑,為什么之前AsyncTask使用配置的線程池執(zhí)行任務(wù)淆两,最多同時執(zhí)行128個任務(wù)断箫,并等待10個, 并且超過限制會報異常呢秋冰?
來看看AsyncTask內(nèi)部的線程池的配置仲义。
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
private static final ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
private static final BlockingQueue<Runnable> sPoolWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
public static final Executor THREAD_POOL_EXECUTOR
=new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
http://zhangfengzhe.blog.51cto.com/8855103/1881644
這部分其實(shí)是線程配置方面的知識,我們在java中構(gòu)建自定義線程池時剑勾,需要用到ThreadPoolExecutor的構(gòu)造方法埃撵。如下所示:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
}
參數(shù)說明如下:
corePoolSize:核心線程數(shù)
maximumPoolSize:最大線程數(shù)
keepAliveTime + unit:線程回收時間
workQueue:任務(wù)較多時暫存到隊(duì)列
threadFactory:執(zhí)行程序創(chuàng)建新線程時使用的工廠
handler:超出線程池容量以及隊(duì)列長度后拒絕任務(wù)的策略
從AsyncTask的構(gòu)建線程池的代碼中可以看出,其中構(gòu)建的是一個corePoolSize為5虽另,maximumPoolSize為128暂刘,任務(wù)隊(duì)列為無界隊(duì)列LinkedBlockingQueue,隊(duì)列容納個數(shù)為10. 根據(jù)線程池處理流程圖:
我們可以知道捂刺,開始可以并行執(zhí)行5個任務(wù)谣拣,當(dāng)任務(wù)個數(shù)超過corePoolSize核心數(shù)時募寨,就會添加到任務(wù)隊(duì)列中,當(dāng)超過10個的時候就會一直構(gòu)建新線程去執(zhí)行任務(wù)森缠,一直到線程數(shù)量達(dá)到128個(線程池的最大數(shù)量)绪商。 所以在3.0以前, AsyncTask最多可以同時執(zhí)行128個任務(wù)辅鲸,同時隊(duì)列中可以有10個在等待。 如果超過這個數(shù)字腹殿,就會報RejectedExcpction的異常(超出線程池容量以及隊(duì)列長度后拒絕任務(wù)的策略)独悴。
另1:構(gòu)建線程池的時候可以使用隊(duì)列,其中無界隊(duì)列LinkedBlockingQueue锣尉,可以在構(gòu)建時指定隊(duì)列容量刻炒。
另2:我在使用ScheduledThreadPoolExecutor線程池的時候遇到了 RejectedExcpction異常,我想ScheduledThreadPoolExecutor使用的線程池的隊(duì)列是無界的自沧,怎么會導(dǎo)致出現(xiàn)這個問題坟奥。 后來看到文檔說明,如果在執(zhí)行任務(wù)的時候線程池已經(jīng)“shutdown" 就會拒絕執(zhí)行拇厢。 所以使用線程池執(zhí)行任務(wù)的時候爱谁,需要先判斷線程池是否已經(jīng)shutdown();