AsyncTask兩種線程池


 
 
AsyncTask兩種線程池
  http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后):
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);
2 b.    asynct.execute(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中引入的線程池:

1、線程池中的工作線程少於5個時,將會創建新的工作線程執行異步任務(紅色表示新任務,下同)

2、線程池中已經有5個線程,緩沖隊列未滿,異步任務將會放到緩沖隊列中等待

3、線程池中已經有5個線程,緩沖隊列已滿,那么線程池將新開工作線程執行異步任務

問題:Android的設備一般不超過2個cpu核心,過多的線程會造成線程間切換頻繁,消耗系統資源。

4、線程池中已經有128個線程,緩沖隊列已滿,如果此時向線程提交任務,將會拋出RejectedExecutionException

問題:拋出的錯誤不catch的話會導致程序FC。

 
新版本
            可能是Google意識到了AsyncTask的局限性了,從Android 3.0開始對AsyncTask的API做出了一些調整:每次只啟動一個線程執行一個任務,完成之后再執行第二個任務,也就是相當於只有一個后台線程在執行所提交的任務
如上 “ Android AsyncTask兩種線程池分析和總結 ”所述
 
 
 
 
 
 
 
 
 
 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM