標籤:android asynctask 線程 源碼 線程池
轉載請註明出處:http://blog.csdn.net/itachi85/article/details/45055365 請看這篇文章之前看一下本作的前篇http://blog.csdn.net/itachi85/article/details/45041923
3.AsyncTask中的線程池 AsyncTask中一共定義了兩個線程池一個是此前我們已經介紹了線程池SerialExecutor,這個是目前我們調用AsyncTask.execute()方法預設使用的線程池,這個在前一篇文章中已經講到過了,另一個是3.0版本之前的預設線程池THREAD_POOL_EXECUTOR。現在我們來回顧一下SerialExecutor的源碼:
private static class SerialExecutor implements Executor { final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>(); Runnable mActive; public synchronized void execute(final Runnable r) { mTasks.offer(new Runnable() { public void run() { try { r.run(); } finally { scheduleNext(); } } }); if (mActive == null) { scheduleNext(); } }
這個預設的線程池同一時間只能處理一個任務,一個任務完成以後才可以執行下一個任務,相當於Executors.newSingleThreadPool()。上面的arrayDeque是一個裝載Runnable的隊列,如果我們一次性啟動了很多個任務,在第一次運行execute()方法的時候會調用ArrayDeque的offer()方法將傳入的Runnable對象添加到隊列的尾部, 然後判斷mActive對象是不是等於null,第一次運行等於null,於是調用scheduleNext()方法。另外在finally中也調用了scheduleNext()方法,這樣保證每次當一個任務執行完畢後,下一個任務才會執行。我們來看看scheduleNext()方法的源碼:
protected synchronized void scheduleNext() { if ((mActive = mTasks.poll()) != null) { THREAD_POOL_EXECUTOR.execute(mActive); } }
首先從runnable隊列的頭部取值,如果不為空白就賦值給mActive對象,然後調用THREAD_POOL_EXECUTOR去執行取出的Runnable對象。THREAD_POOL_EXECUTOR源碼:
private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1;... public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
這是3.0版本之前的線程池,同一時刻能夠啟動並執行線程數為5個,workQueue總大小為128。當我們啟動10個任務,只有5個任務能夠優先執行,其餘的任務放在workQueue中,當workQueue大於128時就會調用RejectedExecutionHandler來做拒絕處理。當然在3.0之前是並沒有SerialExecutor這個類的。如果不希望用預設線程池我們也可以使用這個3.0版本之前的線程池
AsyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
同時3.0版本也提供了executeOnExecutor這個方法可以傳入AsyncTask定義的線程池也可以傳入Executor定義的4種線程池,不知道這四種線程池的可以看http://blog.csdn.net/itachi85/article/details/44874511傳入CachedThreadPool:
LikeListTask mLikeListTask=new LikeListTask();mLikeListTask.executeOnExecutor(Executors.newCachedThreadPool(), null);
當然我們也可以傳入自訂的線程池:
Executor exec =new ThreadPoolExecutor(0, Integer.MAX_VALUE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); new LikeListTask().executeOnExecutor(exec, null);
android線程(二)AsyncTask源碼分析(二)