问题由来

之前看到一篇博文,说AsyncTask不适合运行多任务, 多个任务不会异步执行, 当时只是印象里记住了一下也不确定, 今天把代码看了看, 把原因写出来。

问题的代码演示

 1 public class AsyncTaskDemo  extends AsyncTask<String, Integer, String>{
 2     private final static String TAG = "AsyncTaskTest";
 3
 4     @Override
 5     protected String doInBackground(String... params) {
 6         Log.v(TAG, params[0] + "=================doInBackground===================PID = " + Thread.currentThread().getId());
 7
 8         return params[0];
 9     }
10
11
12 }

1 // 一个按钮的onclick函数
2 public void test(View view) {
3         Log.v("AsyncTaskTest", "CPU_COUNT = " + Runtime.getRuntime().availableProcessors());
4
5         new AsyncTaskDemo().execute("Hello1");
6         new AsyncTaskDemo().execute("Hello2");
7         new AsyncTaskDemo().execute("Hello3");
8         new AsyncTaskDemo().execute("Hello4");
9     }

//logcat里打印出来的结果12-11 16:07:34.865    1979-1979/com.sabo.helloworld V/AsyncTaskTest﹕ CPU_COUNT = 1
12-11 16:07:34.871    1979-2102/com.sabo.helloworld V/AsyncTaskTest﹕ Hello1=================doInBackground===================PID = 161
12-11 16:07:34.872    1979-2103/com.sabo.helloworld V/AsyncTaskTest﹕ Hello2=================doInBackground===================PID = 162
12-11 16:07:34.872    1979-2103/com.sabo.helloworld V/AsyncTaskTest﹕ Hello3=================doInBackground===================PID = 162
12-11 16:07:34.872    1979-2103/com.sabo.helloworld V/AsyncTaskTest﹕ Hello4=================doInBackground===================PID = 162

实验大致辅证了"AsyncTask不适合运行多任务"这个推断, 另一个有趣的结果是非异步执行的时候居然可能不是在一个线程里运行的【看我上面用红色标记的部分】。

分析:

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

    @MainThreadpublic 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);// exec  --> sDefaultExecutorreturn this;}

如果熟悉Java的并发编程的话就知道sDefaultExecutor用于将要完成的任务交给内部已经实现的线程池去执行(有兴趣的话可以去看看Doug Lea写的那本《Java并发编程》)

public static final Executor SERIAL_EXECUTOR = new SerialExecutor();private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;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);}}}

这里的代码就能解释为什么多个AsyncTask一起执行时序列化执行而被异步的了,

1         new AsyncTaskDemo().execute("Hello1"); //mActive == null
2         new AsyncTaskDemo().execute("Hello2"); //mActive != null
3         new AsyncTaskDemo().execute("Hello3"); //mActive != null
4         new AsyncTaskDemo().execute("Hello4"); //mActive != null

上面红色标记的代码可以看出,只有第一个任务直接调用scheduleNext()--->THREAD_POOL_EXECUTOR.execute(mActive), 线程池直接将任务交由线程去执行,而后面几个任务先被放入ArrayDeque<Runnable> mTasks, 没有交给任何线程去执行,

每个任务执行完之后又都要运行上面绿颜色标记的scheduleNext(), 从而依次序序列化执行任务。

上面提到的有趣的事情,既然AsyncTask是序列化执行任务的, 那么线程池里只要一个线程就能满足要求了啊, 为什么会有两个线程。

1     private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
2     private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
3     private static final int KEEP_ALIVE = 1;
4
5     public static final Executor THREAD_POOL_EXECUTOR
6             = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,
7                     TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

上面我把CPU_COUNT的值打印出来是1, 所以这里线程池的线程数就可能是[2, 3]了, 然而对于AsyncTask来说1就够了, 多余1的线程其实是没有什么帮助的。

P.S.

:-)第一次写博客, 加上功力又有限, 欢迎大家指正canbin.zhang#qq.com

转载于:https://www.cnblogs.com/sabo/p/5040685.html

AsyncTask与多任务相关推荐

  1. android AsyncTask 只能在线程池里单个运行的问题

    android 的AysncTask直接调用Execute会在在一个线程池里按调用的先后顺序依次执行. 如果应用的所有网络获取都依赖这个来做,当有一个网络请求柱塞,就导致其它请求也柱塞了. 在3.0 ...

  2. 你真的了解AsyncTask吗?AsyncTask源码分析

    转载请注明出处:http://blog.csdn.net/yianemail/article/details/51611326 1,概述 Android UI是线程不安全的,如果想要在子线程很好的访问 ...

  3. AsyncTask的使用

    概念 AsyncTask是一个抽象类,它是由Android封装的一个轻量级异步类,它的内部封装了两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler ...

  4. 多任务训练的模式结构扩散

    多任务训练的模式结构扩散 Pattern-Structure Diffusion for Multi-Task Learning 论文地址: http://openaccess.thecvf.com/ ...

  5. 深度学习 -- TensorFlow(项目)验证码生成与识别(多任务学习)

    目录 基础理论 一.生成验证码数据集 1.生成验证码训练集 1-0.判断文件夹是否为空 1-1.创建字符集(数字.大小写英文字母) 1-2.随机生成验证码(1000个,长度为4) 2.生成验证码测试集 ...

  6. Linux多任务编程之五:exit()和_exit()函数(转)

    来源:CSDN  作者:王文松   转自:Linux公社 ----------------------------------------------------------------------- ...

  7. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  8. 【Android】AsyncTask异步类

    一.关于AysncTask AsyncTask使得多线程编程更加简单,AsyncTask能在后台线程执行异步任务,并且在UI线程更新界面,而不再需要用户去操作Thread和Handler.AysncT ...

  9. ios4.2文件夹及多任务

    ios4.2的文件夹和多任务可谓是主要特性,但是安装完后我却丝毫不知道该怎么做...在网上找了好久总算解决了 多任务:双击home键,在屏幕下方就会显示当前正在执行的任务,如http://tech.s ...

最新文章

  1. 怎样生成分布式情况下的唯一标示?必须包含网卡字段,以便不同机器生成的唯一标示肯定不一样...
  2. 【C 语言】数组 ( 数组指针 | 数组指针定义 | 直接定义 数组指针 )
  3. 阿里云ECS使用cloudfs4oss挂载OSS
  4. 2011年全国软件大赛模拟题及参考答案(Java本科组)
  5. mysql 判断是否已存在及插入表数据 的 简单存储过程
  6. iOS开发之手势识别
  7. 性能优化 = 改改代码?
  8. 用c语言输出魔方阵答案,如何用C语言输出一个1—16 组成的4*4的魔方阵
  9. 腾讯Tiny OS 组合 NB-IoT,值得程序员一试吗?
  10. 从 CTA 趋势策略的表现看量化投资面临的挑战
  11. 训练集(training)、验证集(validation)和测试集(test)
  12. Python 处理 PDF 的神器 -- PyMuPDF(上)
  13. SSDP协议内容解析
  14. python 多重类继承__init__
  15. 如何用手机远程协助长辈?我找出了6个最佳方法!(免ROOT)
  16. 【CCPC】2022年绵阳站部分题解(ACGM)
  17. 六下计算机教学总结,六年级下册信息技术教学工作总结
  18. Win键无效/Win键失灵/Win键被禁用/Win键+组合键不起作用
  19. 单个form表单内,不同情况显示的不同选项的单选框或多选框的情况下,判断单选框是否存在未选择一个选项情况,并进行提示。
  20. RDKit分子的3D结构

热门文章

  1. 男女薪酬差异扩大 2018年女性薪酬不及男性8成
  2. 老公贷款还不上,妻子有偿还责任吗?
  3. 游牧大地的诗意:看龙力游的草原油画
  4. 尺度空间(Scale space)理论
  5. 蒙特卡罗方法求一个三维积分(论坛帮顶)
  6. java spring redis_spring配置redis(xml+java方式)
  7. 停车场管理系统代码_jsp19109商场商铺停车场服务系统-SSM-Mysql
  8. gitlab git clone 输入密码_gitlab1:部署gitlab
  9. hive数据库numeric_hive中常用的函数
  10. Unity 2017 Game Optimization 读书笔记 The Benefits of Batching