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
|