关于Android 3.0以后AsyncTask默认单一线程的分析

来源:本站
导读:目前正在解读《关于Android 3.0以后AsyncTask默认单一线程的分析》的相关信息,《关于Android 3.0以后AsyncTask默认单一线程的分析》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《关于Android 3.0以后AsyncTask默认单一线程的分析》的详细说明。
简介:在Android里需要大量后台操作的情况下,经常会使用到AsyncTask这个类,比如说加载网络图片,访问服务器的接口,一般的使用情境就是实例化一个AsyncTask的对象mTask

在Android里需要大量后台操作的情况下,经常会使用到AsyncTask这个类,比如说加载网络图片,访问服务器的接口,一般的使用情境就是实例化一个AsyncTask的对象mTask,复写AsyncTask的抽象方法doinBackgroud等等,最后执行task.execute(params),然后就可以在UI线程上方便的取得后台线程的执行结果;

AsyncTask执行中最终触发的是把任务交给线池THREAD_POOL_EXECUTOR来执行,提交的任务并行的在线程池中运行,但这些规则在3.0之后发生了变化,3.0之后提交的任务是串行运行的,执行完一个任务才执行下一个!

先看看3.0以前的代码;

123private static final int CORE_POOL_SIZE = 5;private static final int MAXIMUM_POOL_SIZE = 128;private static final int KEEP_ALIVE = 10;

1public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

3.0以前线程池里核心线程有5个,同时存在的线程数最大不能超过128个,线程池里的线程都是并行运行的;

但是在3.0之后,直接调用execute(params)触发的是sDefaultExecutor的execute(runnable)方法,而不是原来的THREAD_POOL_EXECUTOR

?

123private static final int CORE_POOL_SIZE = CPU_COUNT + 1;private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;private static final int KEEP_ALIVE = 1;

?

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

看看这个sDefaultExecutor与原来的THREAD_POOL_EXECUTOR线程池有什么 差别,sDefaultExecutor实际上是指向SerialExecutor的一个实例,从名字上看是一个顺序执行的executor;

12345678910111213141516171819202122232425262728public 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);}}}</runnable></runnable>

分析SerialExecutor,当提交一个任务,执行一次execute(),向mTasks添加一个runnable,此时mActive为null,接着会执行scheduleNext(),将mActive指向刚刚添加的runbale,并提交到THREAD_POOL_EXECUTOR中执行,接着就线程池中就会执行下面这段代码;

12345try {r.run();} finally {scheduleNext();}

当asyncTask提交大量的任务时,会重复之前的流程,任务都添加至mTasks中了,提交第一个任务之后,mActive便不再为Null了,之后的任务如果要被执行就必需等到前一个任务run方法跑完,也就是try{ }语句块中的run(),前一个任务执行完后,才会调用finally

后面的scheduleNext()从mTasks中取出下一个任务来执行;

分析完上面的代码后,现在对于3.0以后AsyncTask默认情况下同时只存在一个线程顺序执行的原理就了解清楚了;

如果想要提交的任务在能并行执行呢?这在网络图片显示中还是比较有用的;

AsyncTask也为我们提供了另外一种启动方法

?

1public final AsyncTask<params, result=""> executeOnExecutor(Executor exec,Params... params)</params,>

这里可以指定自定义的executor,而不再用SerialExecutor,如果乐意的话当然也可以直接使用用原本的THREAD_POOL_EXECUTOR,这样就可以保证多个任务并行执行了;

提醒:《关于Android 3.0以后AsyncTask默认单一线程的分析》最后刷新时间 2024-03-14 01:05:44,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《关于Android 3.0以后AsyncTask默认单一线程的分析》该内容的真实性请自行鉴别。