1. 多實例並行時,使用 asynchTask.execute()提交的任務是串行執行的.
下面分析原因:
以下是兩個異步實例提交任務:
private void asynchTaskTest() {
// 異步任務1
TestAnsycTask testAnsycTask1 = new TestAnsycTask();
Log.e("TAG", "execute1 ThreadName:" + Thread.currentThread().getName());
testAnsycTask1.execute(new String[]{"111", "2222", "333"});
// 異步任務2
TestAnsycTask testAnsycTask2 = new TestAnsycTask();
Log.e("TAG", "execute2 ThreadName:" + Thread.currentThread().getName());
testAnsycTask2.execute(new String[]{"aaa", "bbbb", "ccc"});
}
private static class TestAnsycTask extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String[] params) {
Log.e("TestAnsycTask", "doInBackground threadName: " + Thread.currentThread().getName());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (String content : params) {
Log.e("TestAnsycTask", " content: " + content);
if (isCancelled())
break;
}
return null;
}
}
結果顯示任務testAnsycTask1執行完畢後,才執行testAnsycTask2的任務,是串行的
2019-07-12 15:37:01.454 5865-5865/com.pp.sqlitedemo E/TAG: execute1 ThreadName:main
2019-07-12 15:37:01.454 5865-5865/com.pp.sqlitedemo E/TAG: execute2 ThreadName:main
2019-07-12 15:37:01.455 5865-5926/com.pp.sqlitedemo E/TestAnsycTask: doInBackground threadName: AsyncTask #1
2019-07-12 15:37:01.455 5865-5926/com.pp.sqlitedemo E/TestAnsycTask: content: 111
2019-07-12 15:37:01.455 5865-5926/com.pp.sqlitedemo E/TestAnsycTask: content: 2222
2019-07-12 15:37:01.455 5865-5926/com.pp.sqlitedemo E/TestAnsycTask: content: 333
2019-07-12 15:37:01.455 5865-5927/com.pp.sqlitedemo E/TestAnsycTask: doInBackground threadName: AsyncTask #2
2019-07-12 15:37:01.455 5865-5927/com.pp.sqlitedemo E/TestAnsycTask: content: aaa
2019-07-12 15:37:01.455 5865-5927/com.pp.sqlitedemo E/TestAnsycTask: content: bbbb
2019-07-12 15:37:01.455 5865-5927/com.pp.sqlitedemo E/TestAnsycTask: content: ccc
原因:
public class AnsyncTask{
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
// 進入 execute(),內部調用的是executeOnExecutor(sDefaultExecutor, params)
public final AsyncTask<Params, Progress, Result> execute(Params... params{
return executeOnExecutor(sDefaultExecutor, params);
}
// 進入 executeOnExecutor()
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
// 最終任務是在這裏提交的,而exec是傳入的 sDefaultExecutor
exec.execute(mFuture);
return this;
}
}
① 進入 execute(),內部調用的是executeOnExecutor(sDefaultExecutor, params)
②進入executeOnExecutor(),可以看到任務是通過傳入的sDefaultExecutor提交的,而sDefaultExecutor是靜態的
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
因爲sDefaultExecutor是靜態共享的,所以execute()方法提交的任務都緩存到了sDefaultExecutor內部同一個隊列之中,所以是串行執行的
那麼如何並行處理任務了?
從Android 3.0開始AsyncTask增加了executeOnExecutor方法,
並行傳入: AsyncTask.THREAD_POOL_EXECUTOR(線程池效果)
串行傳入: AsyncTask.SERIAL_EXECUTOR
並行處理任務,方法如下:
private void asynchTaskTest() {
// 異步任務1
TestAnsycTask testAnsycTask1 = new TestAnsycTask();
Log.e("TAG", "execute1 ThreadName:" + Thread.currentThread().getName());
// testAnsycTask1.execute(new String[]{"111", "2222", "333"});
testAnsycTask1.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{"111", "2222", "333"});
// 異步任務2
TestAnsycTask testAnsycTask2 = new TestAnsycTask();
Log.e("TAG", "execute2 ThreadName:" + Thread.currentThread().getName());
// testAnsycTask2.execute(new String[]{"aaa", "bbbb", "ccc"});
testAnsycTask2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[]{"aaa", "bbbb", "ccc"});
}
結果,並行:
2019-07-12 15:40:44.298 7096-7096/com.pp.sqlitedemo E/TAG: execute1 ThreadName:main
2019-07-12 15:40:44.298 7096-7096/com.pp.sqlitedemo E/TAG: execute2 ThreadName:main
2019-07-12 15:40:44.299 7096-7157/com.pp.sqlitedemo E/TestAnsycTask: doInBackground threadName: AsyncTask #2
2019-07-12 15:40:44.299 7096-7156/com.pp.sqlitedemo E/TestAnsycTask: doInBackground threadName: AsyncTask #1
2019-07-12 15:40:44.339 7096-7157/com.pp.sqlitedemo E/TestAnsycTask: content: aaa
2019-07-12 15:40:44.339 7096-7156/com.pp.sqlitedemo E/TestAnsycTask: content: 111
2019-07-12 15:40:44.339 7096-7156/com.pp.sqlitedemo E/TestAnsycTask: content: 2222
2019-07-12 15:40:44.339 7096-7157/com.pp.sqlitedemo E/TestAnsycTask: content: bbbb
2019-07-12 15:40:44.339 7096-7156/com.pp.sqlitedemo E/TestAnsycTask: content: 333
2019-07-12 15:40:44.339 7096-7157/com.pp.sqlitedemo E/TestAnsycTask: content: ccc