AsyncTask里的线程池串行、并行逻辑详解。

本文详细解析了Android中的AsyncTask如何实现线程池和Handler,以支持UI线程与工作线程间的异步操作。AsyncTask内置的THREAD_POOL_EXECUTOR在多核CPU下执行并行,单核下串行;而SERIAL_EXECUTOR无论单核多核均执行串行任务。通过execute()和executeOnExecutor()方法,开发者可以选择串行或并行执行任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AsyncTask里面封装了线程池和Handler,所以很是方便我们使用它来处理ui线程和工作线程之间的异步任务的逻辑工作。

AsyncTask里面的的线程池的实现是用ThreadPoolExecutor来实现的。然而ThreadPoolExecutor的的执行逻辑在cpu多核情况下,执行顺序是不确定的,也就是并行的。

AsyncTask里面有两个线程池的静态常量 这就保证了整个逻辑内只有一个线程池。

  • THREAD_POOL_EXECUTOR 多核下,并行,单核下串行。
  • SERIAL_EXECUTOR,单核和多核下都是串行。

下面是THREAD_POOL_EXECUTOR的实现和定义。

    /**
     * An {@link Executor} 并行执行的线程池.
     */
    public static final Executor THREAD_POOL_EXECUTOR;

    static {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
                sPoolWorkQueue, sThreadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
        threadPoolExecutor.allowCoreThreadTimeOut(true);
        THREAD_POOL_EXECUTOR = threadPoolExecutor;
    }

下面是SERIAL_EXECUTOR的实现。SERIAL_EXECUTOR的实现是基于THREAD_POOL_EXECUTOR,但加入了串行逻辑。具体的实现逻辑全在scheduleNext这个方法里面。如下。

   private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
    
    /**
     * 一个{@link Executor},按串行顺序一次执行一个任务。这种序列化对于特定的流程是全局的。
     */
    public static final Executor SERIAL_EXECUTOR = new SerialExecutor();

    /**
     * 串行Executor,基于THREAD_POOL_EXECUTOR实现串行
     */
    private static class SerialExecutor implements Executor {
        /**
         * 串行任务的双端队列
         */
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;

        @Override
        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                @Override
                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);
            }
        }
    }
   

AsyncTask提供了几个执行方法。

1,串行。AsyncTask提供了静态方法execute,直接传入Runnable对象,进行串行执行,注意该方法需要在UI线程中调用

                    AsyncTask.execute(new Runnable() {
                        @Override
                        public void run() {
                            //异步逻辑
                        }
                    });

看一下静态方法execute的源码,使用的是默认的sDefaultExecutor执行的。

    @MainThread
    public static void execute(Runnable runnable) {
        sDefaultExecutor.execute(runnable);
    }

默认情况下,sDefaultExecutor的默认值是SERIAL_EXECUTOR。而SERIAL_EXECUTOR是实现是AsyncTask的静态内部类SerialExecutor。SerialExecutor的实现是串行的。所以,默认情况下sDefaultExecutor的行为是串行的。

2,串行,AsyncTask还提供了一个execute成员方法。里面调用的executeOnExecutor成员方法传入的是sDefaultExecutor线程池,

    @MainThread
    public final AsyncTask<Params, Progress, Result> execute(Params... params) {
        return executeOnExecutor(sDefaultExecutor, params);
    }

再看executeOnExecutor方法。

    @MainThread
    public final MyAsyncTask<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;
    }

3,串行,并行随你选。

executeOnExecutor方法支持你指定线程池。传入THREAD_POOL_EXECUTOR并行,传入SERIAL_EXECUTOR串行。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值