`

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

 
阅读更多

原文:http://www.2cto.com/kf/201411/348411.html

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

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

先看看3.0以前的代码;

 

  1. private static final int CORE_POOL_SIZE = 5;  
  2. private static final int MAXIMUM_POOL_SIZE = 128;  
  3. private static final int KEEP_ALIVE = 10;  
  4.   
  5. public 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

 

1
2
3
privatestatic final int CORE_POOL_SIZE = CPU_COUNT + 1;
privatestatic final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2+ 1;
privatestatic final int KEEP_ALIVE = 1;

 

1
2
3
publicstatic void execute(Runnable runnable) {
        sDefaultExecutor.execute(runnable);
    }

 

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

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
publicstatic final Executor SERIAL_EXECUTOR = newSerialExecutor();
privatestatic volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
 
 privatestatic class SerialExecutor implementsExecutor {
        finalArrayDeque<runnable> mTasks = newArrayDeque<runnable>();
        Runnable mActive;
 
        publicsynchronized void execute(finalRunnable r) {
            mTasks.offer(newRunnable() {
                publicvoid run() {
                    try{
                        r.run();
                    }finally{
                        scheduleNext();
                    }
                }
            });
            if(mActive == null) {
                scheduleNext();
            }
        }
 
        protectedsynchronized 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中执行,接着就线程池中就会执行下面这段代码;

1
2
3
4
5
try{
                        r.run();
                    }finally{
                        scheduleNext();
                    }


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

 

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

 

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

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

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


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

分享到:
评论

相关推荐

    在Android中使用AsyncTask和Handler线程间交互的方式

    在Android中使用AsyncTask和Handler线程间交互的方式,详情参见博客:http://www.cnblogs.com/plokmju/p/android_AsyncTask.html和http://www.cnblogs.com/plokmju/p/android_Handler.html

    Android中AsyncTask实现多线程计数

    AsyncTask是Android提供的一种轻量级的异步任务处理框架,它允许开发者在后台线程执行计算,并在UI线程更新结果,非常适合进行简单的异步操作,如网络请求、数据计算等。本篇将详细讲解如何在Android中使用AsyncTask...

    AsyncTask 异步多线程加载Demo

    - 从Android 3.0(API级别11)开始,`AsyncTask`默认在单独的线程池中运行,而不是主线程。这意味即使不开启新线程,`doInBackground()`也会在非UI线程执行。 - `AsyncTask`并不适合大量或复杂的并发任务,因为它...

    使用AsyncTask提高android线程的效率

    2. **版本兼容性**:从Android 3.0(API级别11)开始,`AsyncTask`的执行默认是在单线程模式下,即所有任务都会顺序执行。如果需要多线程执行,需在应用清单文件中声明`android:targetSdkVersion`为11或更高。 3. **...

    Android开发之AsyncTask机制及使用细节例子源码

    3. **版本兼容性**:自Android 3.0(API级别11)开始,AsyncTask默认在单独的线程池中执行,而在早期版本中,它们默认在主线程中执行。因此,在不同Android版本上使用AsyncTask时需注意适配。 4. **内存泄漏**:...

    android线程 Handler Message Queue AsyncTask线程模型 线程交互 + 修改Button样式 示例 最终easy整合版

    以上就是关于Android线程模型和线程交互的详解,包括Handler、Message Queue和AsyncTask的使用,以及修改Button样式的实例。理解并熟练运用这些技术,可以极大地提高Android应用的性能和用户体验。通过不断实践和...

    android asyncTask线程应用

    - Android 3.0(API级别11)及更高版本中,AsyncTask的执行默认是在单线程池中,这可能导致并发执行的任务被串行化。如果需要并行执行,可以通过`executeOnExecutor()`方法指定线程池。 在TextAsyncTask这个文件中...

    Android AsyncTask 源码解析

    AsyncTask 是 Android 平台上一个非常重要的工具类,用于在后台线程执行耗时操作,然后在 UI 线程更新结果,从而避免了因长时间运行任务而导致的 ANR(Application Not Responding)错误。在深入探讨 AsyncTask 的...

    android使用AsyncTask实现多线程下载实例

    `AsyncTask`是Android提供的一种轻量级的并发工具,它简化了在主线程与工作线程间传递数据以及更新UI的操作。在本实例中,我们将探讨如何使用`AsyncTask`来实现多线程下载。 首先,我们来看一下`DownloadTask`这个...

    01_AsyncTask_演示线程阻塞

    在博客《Android专题之AsyncTask(一)基本概念介绍》中,我们详细分析了`AsyncTask`的优缺点,以及在实际项目中如何合理使用。通过学习这些内容,开发者可以更好地理解和运用`AsyncTask`,提高应用的响应速度和用户...

    Android使用AsyncTask实现多线程下载的方法

    - 版本兼容性:从Android 3.0(API级别11)开始,AsyncTask默认是在后台线程池中运行的,而在早期版本中是在单独的线程中运行。这可能会影响性能和并发行为,需要根据目标平台进行调整。 总之,Android的AsyncTask...

    12_Android 多线程AsyncTask详解

    为了避免这种情况,Android引入了AsyncTask,这是一个轻量级的并发框架,用于简化在后台线程执行耗时操作并在完成后更新UI的工作流程。AsyncTask包含三个泛型参数,分别代表后台操作的输入类型(Params)、后台操作...

    Android-使用AsyncTask实现的多任务多线程下载的Demo支持断点续传。

    这个Demo,"Android-使用AsyncTask实现的多任务多线程下载的Demo支持断点续传",展示了如何高效且智能地管理下载过程。我们将深入探讨AsyncTask、多线程以及断点续传的概念。 首先,`AsyncTask`是Android提供的一种...

    android中AsyncTask的用法

    在Android应用开发中,AsyncTask是一个用于在后台线程执行耗时操作并更新UI的工具类,它是Android 1.5版本引入的。AsyncTask的设计初衷是为了简化异步编程,避免直接操作线程和Handler带来的复杂性。下面我们将详细...

    Android AsyncTask多线程详解

    Android Asynctask 先小试牛刀,了解一下各个方法执行过程,关注博客http://himici.com/

    Android3.0从自己建立的httpd下载文件

    Android 3.0引入了对多线程下载的支持,使得我们可以更高效地处理大文件下载。以下是一些关键步骤: 1. **设置权限**:在AndroidManifest.xml文件中,必须声明`INTERNET`权限,以允许应用访问网络资源: ```xml ...

Global site tag (gtag.js) - Google Analytics