AsyncTask(多任务串行/并行)简单分析

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

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章