zoukankan      html  css  js  c++  java
  • AsyncTask两种线程池

     
     
    AsyncTask两种线程池
    1.THREAD_POOL_EXECUTOR, 异步线程池
    使用
    首先创建一个继承自AsyncTask的MyAsyncTask类,然后调用
    1 MyAsyncTask asynct = new MyAsyncTask(task);
    2 asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);
    原理
    1.corePoolSize=CPU核心数+1;
    2.maximumPoolSize=2倍的CPU核心数+1;
    3.核心线程无超时机制,非核心线程在闲置时间的超时时间为1s
    4.任务队列的容量为128
     
      当一个任务通过asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0)方法欲添加到线程池时:
    • 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
    • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
    • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
    • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
    • 当线程池中的线程数量大于 corePoolSize时,如果某线程(非核心线程)空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
    也就是:处理任务的优先级为:
    核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务(一般为抛出java.util.concurrent.RejectedExecutionException异常)。
     

    2.SERIAL_EXECUTOR,同步线程池
    使用
    它是默认的Executor,所以可以直接调用,所以可以有两种调用方法。
    1 a.    asynct.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, 0);
    2 b.    asynct.execute(0);
    原理
    SERIAL_EXECUTOR在THREAD_POOL_EXECUTOR的基础上添加了一个mTasks的集合来保证任务顺序执行(异步)
     
    AsyncTask在不同SDK版本中的区别
    旧版本
      通过查阅官方文档发现,AsyncTask首次引入时,异步任务是在一个独立的线程中顺序地执行,也就是说一次只能执行一个任务,不能并行地执行,从1.6开始,AsyncTask中引入了线程池,支持同时执行5个异步任务,也就是说同时只能有5个线程运行,超过的线程只能等待,等待前面的线程某个执行完了才被调度和运行。换句话说,如果一个进程中的AsyncTask实例个数超过5个,那么假如前5个都运行很长时间的话,那么第6个只能等待机会了。这是AsyncTask的一个限制,而且对于2.3以前的版本无法解决。如果你的应用需要大量的后台线程去执行任务,那么你只能放弃使用AsyncTask,自己创建线程池来管理Thread,或者干脆不用线程池直接使用Thread也无妨。不得不说,虽然AsyncTask较Thread使用起来比较方便,但是它最多只能同时运行5个线程,这也大大局限了它的实力,你必须要小心的设计你的应用,错开使用AsyncTask的时间,尽力做到分时,或者保证数量不会大于5个,否则就可能遇到上面提到的问题。
    从1.6开始,AsyncTask中引入的线程池:

    1、线程池中的工作线程少于5个时,将会创建新的工作线程执行异步任务(红色表示新任务,下同)

    2、线程池中已经有5个线程,缓冲队列未满,异步任务将会放到缓冲队列中等待

    3、线程池中已经有5个线程,缓冲队列已满,那么线程池将新开工作线程执行异步任务

    问题:Android的设备一般不超过2个cpu核心,过多的线程会造成线程间切换频繁,消耗系统资源。

    4、线程池中已经有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException

    问题:抛出的错误不catch的话会导致程序FC。

     
    新版本
             可能是Google意识到了AsyncTask的局限性了,从Android 3.0开始对AsyncTask的API做出了一些调整:每次只启动一个线程执行一个任务,完成之后再执行第二个任务,也就是相当于只有一个后台线程在执行所提交的任务
    如上 “Android AsyncTask两种线程池分析和总结”所述
     
     
     
     
     
     
     
     
     
     





  • 相关阅读:
    Java 线程池概念、原理、简单实现
    Java 中的等待唤醒机制透彻讲解
    Java 多线程安全问题简单切入详细解析
    理解 Java 多线程
    Java 异常的处理
    Android MediaPlayer的生命周期
    Node.js 撸第一个Web应用
    Android简易实战教程--第三十四话《 自定义SeekBar以及里面的一些小知识》
    使用Intent传递对象
    Android 异步查询框架AsyncQueryHandler的使用
  • 原文地址:https://www.cnblogs.com/Doing-what-I-love/p/5532984.html
Copyright © 2011-2022 走看看