AsyncTask優缺點(兩種線程池)

 
 
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);
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兩種線程池分析和總結”所述
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章