美文网首页编程设计之AndroidAndroid 基础知识
AsyncTask问题:多个task是串行执行还是并行的

AsyncTask问题:多个task是串行执行还是并行的

作者: 王小贱_ww | 来源:发表于2017-08-04 10:53 被阅读668次
    在封装Retrofit下载文件时:
     final SaveFileTask task = new SaveFileTask(REQUEST, SUCCESS);
    //继承AsyncTask
                        task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, DOWNLOAD_DIR, EXTENSION, responseBody, NAME);
    为什么这个我们不是调用excute()方法?往下看
    

    AsyncTask的execute()函数

      @MainThread
        public final AsyncTask<Params, Progress, Result> execute(Params... params) {
            return executeOnExecutor(sDefaultExecutor, params);
    调用executeOnExecutor()方法
        }
    
    @MainThread
        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.execute(mFuture);//这一行是重点
    
            return this;
        }
    
    
    • exec是什么?是调用exceute()时传入的sDefaultExecutor
    • sDefaultExecutor是什么? 是它的一个实例。 new SerialExecutor();
    • sDefaultExecutor是SerialExecutor的一个实例,而且它是个静态变量。也就是说,一个进程里面所有AsyncTask对象都共享同一个SerialExecutor对象。
      那么所有的秘密就在于SerialExecutor的execute函数了。
    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();
                }
            }
    
            protected synchronized void scheduleNext() {
                if ((mActive = mTasks.poll()) != null) {
                    THREAD_POOL_EXECUTOR.execute(mActive);
                }
            }
        }
    
    • SerialExecutor是一个一个执行任务的,而所有的对象共享一个 SerialExecutor对象(静态成员),所以多个AsyncTask是串行的。demo:
    final AsyncTask task = new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    Log.e("tag", "task 1 " + "  start");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("tag", "task 1 " + "  end");
                    return null;
                }
            };
            task.execute();
            // task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    
    
            final AsyncTask task2 = new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    Log.e("tag", "task 2 " + "  start");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("tag", "task 2 " + "  end");
                    return null;
                }
            };
            task2.execute();
            // task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    
    1.png

    如何并行执行多个AsyncTask对象

    使用THREAD_POOL_EXECUTOR
     public static final Executor THREAD_POOL_EXECUTOR
                = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
                        TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
    线程池中核心线程数、最大线程数。。。。。怎么调度的再议,但是有一点可以肯定,它不是排队在一个线程里面执行的
    
     final AsyncTask task = new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    Log.e("tag", "task 1 " + "  start");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("tag", "task 1 " + "  end");
                    return null;
                }
            };
            //   task.execute();
            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    
    
            final AsyncTask task2 = new AsyncTask() {
                @Override
                protected Object doInBackground(Object[] params) {
                    Log.e("tag", "task 2 " + "  start");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e("tag", "task 2 " + "  end");
                    return null;
                }
            };
            //   task2.execute();
            task2.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
    
        }
    
    2.png

    相关文章

      网友评论

        本文标题:AsyncTask问题:多个task是串行执行还是并行的

        本文链接:https://www.haomeiwen.com/subject/gbkvlxtx.html