AsyncTask兩種線程池
1.THREAD_POOL_EXECUTOR, 異步線程池
使用
首先建立一個繼承自AsyncTask的MyAsyncTask類,而後調用
1 |
MyAsyncTask asynct = new MyAsyncTask(task); |
2 |
asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0 ); |
原理
1.
corePoolSize
=CPU核心數+1;
2.
maximumPoolSize
=2倍的CPU核心數+1;
3.核心線程無超時機制,非核心線程在閒置時間的超時時間爲
1s
;
4.任務隊列的容量爲
128
。
當一個任務經過asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0)方法欲添加到線程池時:
- 若是此時線程池中的數量小於corePoolSize,即便線程池中的線程都處於空閒狀態,也要建立新的線程來處理被添加的任務。
- 若是此時線程池中的數量等於 corePoolSize,可是緩衝隊列 workQueue未滿,那麼任務被放入緩衝隊列。
- 若是此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,而且線程池中的數量小於maximumPoolSize,建新的線程來處理被添加的任務。
- 若是此時線程池中的數量大於corePoolSize,緩衝隊列workQueue滿,而且線程池中的數量等於maximumPoolSize,那麼經過 handler所指定的策略來處理此任務。
- 當線程池中的線程數量大於 corePoolSize時,若是某線程(非核心線程)空閒時間超過keepAliveTime,線程將被終止。這樣,線程池能夠動態的調整池中的線程數。
也就是:處理任務的優先級爲:
核心線程corePoolSize、任務隊列workQueue、最大線程maximumPoolSize,若是三者都滿了,使用handler處理被拒絕的任務(通常爲
拋出java.util.concurrent.RejectedExecutionException異常
)。
2.SERIAL_EXECUTOR,同步線程池
使用
它是默認的Executor,因此能夠直接調用,因此能夠有兩種調用方法。
1 |
a. asynct.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, 0 ); |
原理
SERIAL_EXECUTOR在THREAD_POOL_EXECUTOR的基礎上添加了一個mTasks的集合來保證任務順序執行(異步)
AsyncTask在不一樣SDK版本中的區別
舊版本
經過查閱官方文檔發現,AsyncTask首次引入時,異步任務是在一個獨立的線程中順序地執行,也就是說一次只能執行一個任務,不能並行地執行,從1.6開始,AsyncTask中引入了線程池,支持同時執行5個異步任務,也就是說同時只能有5個線程運行,超過的線程只能等待,等待前面的線程某個執行完了才被調度和運行。換句話說,若是一個進程中的AsyncTask實例個數超過5個,那麼假如前5個都運行很長時間的話,那麼第6個只能等待機會了。這是AsyncTask的一個限制,並且對於2.3之前的版本沒法解決。若是你的應用須要大量的後臺線程去執行任務,那麼你只能放棄使用AsyncTask,本身建立線程池來管理Thread,或者乾脆不用線程池直接使用Thread也無妨。不得不說,雖然AsyncTask較Thread使用起來比較方便,可是它最多隻能同時運行5個線程,這也大大侷限了它的實力,你必需要當心的設計你的應用,錯開使用AsyncTask的時間,盡力作到分時,或者保證數量不會大於5個,不然就可能遇到上面提到的問題。
從1.6開始,AsyncTask中引入的線程池:
一、線程池中的工做線程少於5個時,將會建立新的工做線程執行異步任務(紅色表示新任務,下同)html
二、線程池中已經有5個線程,緩衝隊列未滿,異步任務將會放到緩衝隊列中等待java
三、線程池中已經有5個線程,緩衝隊列已滿,那麼線程池將新開工做線程執行異步任務android
問題:Android的設備通常不超過2個cpu核心,過多的線程會形成線程間切換頻繁,消耗系統資源。git
四、線程池中已經有128個線程,緩衝隊列已滿,若是此時向線程提交任務,將會拋出RejectedExecutionExceptiongithub
問題:拋出的錯誤不catch的話會致使程序FC。web
新版本
多是Google意識到了AsyncTask的侷限性了,從Android 3.0開始對AsyncTask的API作出了一些調整:每次只啓動一個線程執行一個任務,完成以後再執行第二個任務,也就是至關於只有一個後臺線程在執行所提交的任務
(
如上 「
Android AsyncTask兩種線程池分析和總結
」所述
)