Android AsyncTask內部線程池非同步執行任務機制簡要分析

來源:互聯網
上載者:User

標籤:out   init   方法   factory   seconds   輸出   max   clock   logs   

如下分析針對的API 25的AsyncTask的源碼:

  使用AsyncTask如果是調用execute方法則是同步執行任務,想要非同步執行任務可以直接調用executeOnExecutor方法,多數情況下我們會使用AsyncTask內部靜態線程池,

THREAD_POOL_EXECUTOR,這裡並不是要分析AsyncTask內部的流程,而是簡單介紹下線程池的工作流程。可以看到THREAD_POOL_EXECUTOR的配置如下:

new ThreadPoolExecutor( CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

簡單介紹下ThreadPoolExecutor的幾個參數:

        

  int corePoolSize,核心線程數,可以一直存活線上程池中,除非設定了allowCoreThreadTimeOut,即允許核心線程逾時。 int maximumPoolSize, 線程池中允許的最大線程數。long keepAliveTime,  當線程池中的線程數超過核心線程數時,非核心線程在等待keepAliveTime時間終止,即非核心線程空等待任務(存活時間)的逾時時間是keepAliveTime,TimeUnit unit, 逾時時間的單位,BlockingQueue<Runnable> workQueue, 緩衝任務隊列,ThreadFactory threadFactory 用於建立新線程,可以設定線程優先順序等。具體可以查看API文檔或java.util.concurrent.ThreadPoolExecutor的源碼

        

         具體來說,當一個任務被提交到線程池後,會先看核心線程是否都有任務正在執行,如果核心線程有空閑,則核心線程執行任務,否則將任務添加到緩衝隊列中,待核心線程執行完任務後取緩衝隊列中的任務執行。如果任務較多,緩衝隊列添加滿了,且還有任務提交,那麼會啟動非核心線程執行任務,如果非核心線程數也全部都在工作,即線程池中的線程數達到了最大線程數 MAXIMUM_POOL_SIZE的限制時,再提交任務到線程池則會報拒絕執行任務的異常 java.util.concurrent.RejectedExecutionException

 

  可以用如下代碼簡單測試下:

  先自訂一個AsyncTask

  

static int index = 1;
static class MyAsyncTask extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { SystemClock.sleep(2000); return null; } @Override protected void onPostExecute(Void aVoid) { Log.d(this.getClass().getSimpleName(), "task#" + index + " had executed."); index++; } }

  這裡為了能夠看到如上表述的過程,在doInbackground中讓線程睡眠2秒,並對每個AsyncTask輸出執行完成的log,附帶index標識是第幾個。

 

  然後提交任務到線程池中

        int CPU_COUNT = Runtime.getRuntime().availableProcessors();        int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));        int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;        int taskMaxCounts =  MAXIMUM_POOL_SIZE + 128;        for (int i = 0 ; i < taskMaxCounts; i++ ) {            new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void)null);        }

  最大可同時容納的任務數即: MAXIMUM_POOL_SIZE + 128 (緩衝隊列任務數), 針對API25的版本, 如何CPU是4核心,那麼最大任務數是 4 * 2 + 1 + 128 = 137 .

  當線程池中線程都有任務正在執行且緩衝隊列已滿時,繼續往線程池中提交任務則會報異常,這裡可以將taskMaxCounts 改為 MAXIMUM_POOL_SIZE + 129,

  再次運行程式則會看到異常log資訊

  

 FATAL EXCEPTION: main   Process: com.aquarius.test, PID: 22425   java.lang.RuntimeException: Unable to start activity ComponentInfo{com.aquarius.test/com.http.study.demo.VolleyActivity}: java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0]   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2449)   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2509)   at android.app.ActivityThread.access$1000(ActivityThread.java:153)   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1373)   at android.os.Handler.dispatchMessage(Handler.java:102)   at android.os.Looper.loop(Looper.java:154)   at android.app.ActivityThread.main(ActivityThread.java:5524)   at java.lang.reflect.Method.invoke(Native Method)   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:740)   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:630)   Caused by: java.util.concurrent.RejectedExecutionException: Task [email protected] rejected from [email protected][Running, pool size = 9, active threads = 9, queued tasks = 128, completed tasks = 0]              at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2014)              at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)              at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1340)              at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:607)

  

Android AsyncTask內部線程池非同步執行任務機制簡要分析

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.