AsyncTask 是 Single Thread,一個 task 接著一個 task 執行;從 Android 1.6(DONUT) 一直到
Android 2.3(GINGERBREAD),AsyncTask 變成了 Multi-Thread,當 tasks 剛好等於 5 個時,
最多就可以同時執行 5 個 threads (CORE_POOL_SIZE=5) 來完成 tasks,如果又多 1 個 task,
就會放到 queue 裡,這個 queue 的大小為 10,直到 queue 放不下時,才會在建立一個 thread
來處理新進的 task,最多可有 128 (MAXIMUM_POOL_SIZE) 個 threads 同時處理 tasks,而
tasks 最多可有 128+10=138 個,超過時會發生 java.util.concurrent.RejectedExecutionException。
以上所提到的定義值,可在 AsyncTask.java 的原始碼中看到:
// Source code of Android 4.2.1 r.1.2 public abstract class AsyncTask <Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; ... private static final BlockingQueue<runnable> sPoolWorkQueue = new LinkedBlockingQueue<runnable>(10); ...Android 4.4 之後,CORE_POOL_SIZE 改為 CPU_COUNT+1,MAXIMUM_POOL_SIZE 改為 CPU_COUNT*2+1,queue 的大小改為 128,所以 threads 變少了(猜想應該是為了效能的關係),queue 變大了。
// Source code of Android 4.4 r1 // http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/os/AsyncTask.java#AsyncTask public abstract class AsyncTask <Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); private static final int CORE_POOL_SIZE = CPU_COUNT + 1; private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1; private static final int KEEP_ALIVE = 1; ... private static final BlockingQueue<runnable> sPoolWorkQueue = new LinkedBlockingQueue<runnable>(128); ...
從 Android 3.0(HONEYCOMB) 之後又改回了 Single Thread。Single Thread 版本的 tasks 最多
大小則取決於記憶體,因為是使用 ArrayDeque 來存放 tasks:
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() { ...
另外,想要使用之前 Multi-Thread 的版本就要呼叫
executeOnExecutor(THREAD_POOL_EXECUTOR, Object []),而不是原本的 execute。
參考資料:
沒有留言:
張貼留言