Android的线程与线程池

     1)从用途来看,Android的线程分为主线程和子线程;主线程处理与界面相关的事情;子线程处理耗时操作。
   2)线程的形式:AsyncTask,IntentService和HandlerThread;AsyncTask封装了线程池和Handler,主要是为了在子线程中更新UI;HandlerThread是一种消息循环的线程;IntentService是一个服务,方便执行后台服务。
一、AsyncTask
1.1 AsyncTask的使用
    AsyncTask是一个抽象泛型类,它提供Params,Progress和Result这三个泛型参数。其中Params表示参数的类型;Progress表示后台任务执行进度的类型;Result表示返回结果的类型。
AsyncTask类的声明:

AsyncTask的核心方法:
    1)doPreExecute():在主线程中执行;在任务开始前被调用,可做一些准备工作;
    2)doBackground(Params...params):在线程池中执行用于执行异步任务;在此方法内部会通过调用onProgressUpdate()来更新任务执行。
    3)onProgressUpdate(Progress...values):在主线程中执行后台任务进度发生变化时会执行该方法。
    4)onPostExecute(Result result):在主线程中执行;在doBackground执行完后调用。
AsyncTask注意的地方
    1)AsyncTask的类必须在主线程中加载;
    2)AsyncTask的对象必须在主线程中创建;
    3)execute()方法必须在主线程中调用;
    4)一个AsyncTask对象只能被执行一次;
    5)在Android1.6之前,AsyncTask是串行执行的;Android1.6-3.0,AsyncTask是并行执行的;Android3.0以后,串行和并行都可(并行executeOnExecutor()来执行)
1.2 AsyncTask的工作原理
 1.2.1 从execute方法开始分析,在execute方法内调用executeOnExecutor方法
    
代码中,1)sDefaultExecutor是一个串行的线程池:所有的AsyncTask任务都会在这个线程池进行排队。2)在executeOnExecutor方法中,AsyncTask的onPreExecutor()方法先执行;3)将params参数保存在mWorker中(这个mWorker会被封装成FutureTask对象(充当Runnable),这次封装是在AsyncTask构造函数中完成),接着讲这个FutureTask交给线程池SerialExecutor(实现如下)的execute方法处理。


    1)将FutureTask对象插入到任务队列mTasks中;
    2)如果此时没有活动的AsyncTask任务,就调用SerialExecutor的scheduleNext()方法执行下一个AsyncTask任务(由另外线程池来执行任务);
    3)当任务完成后,SerialExecutor会执行其他AsyncTask任务。
总结:AsyncTask有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(IntentHandler)线程池SerialExecutor用于任务的排队;线程池THREAD_POOL_EXECUTOR用于执行任务;IntentHandler用于将执行环境线程池切换到主线程。
下面来看看AsyncTask构造方法,才能明白doBackground()为什么执行在线程池中

    由于在FutureTask的run方法内会调用mWorker的call方法(FutureTask封装了mWorker),而FutureTask是在线程池中执行的,这样导致mWorker的call方法在线程池中执行。而doBackground方法是在mWorker的call内部的,所以看到这里就回答了刚才的问题。
再来看看,线程池中执行完doBackground方法后,怎么回到主线程的?
同样的,在mWorker的call方法执行完doBackground后,将其返回结果通过postResult方法进行返回。
    
    在postResult方法内会通过sHandler发送一个MESSAGE_POST_RESULT消息,这样就从线程池切换到主线程。
    最后看看sHandler的实现,代码如下:
    
    sHandler是一个静态对象,其必须要在主线程中创建。

二、IntentService
    1)特点:IntentService继承Service并且是一个抽象类,因此必须创建其子类才能使用。
    2)优点:IntentService用于执行后台任务,当任务结束后会自动停止,优先级比线程高。
2.1 IntentService的实现
    IntentService封装HandlerThread和Handler,代码如下:

    IntentService被启动时,首先onCreate方法被调用:1)创建一个HandlerThread;2)使用它的Looper来构建一个Handler对象mServiceHandler---->导致mServiceHandler发送的消息最终会在HandlerThread中执行。
    接着onStartCommand方法被调用去执行每个后台任务的intent。下面是onStartCommand的代码(通过onStart执行):

    IntentService仅通过mServiceHandler发送一个消息,这个消息会在HandlerThread中被处理。mServiceHandler收到消息后,会将这个Intent传递给onHandlerIntent方法处理。ServiceHandler代码如下:

    onHandlerIntent方法是个抽象方法,需要在子类去实现作用是从Intent参数中区分具体的任务并执行这些任务。

三、Android中的线程池
线程池的好处:
    1)重用线程池中的线程,避免因为线程创建和销毁带来的开销;
    2)能有效的控制线程池的最大并发数,避免线程间的抢占资源引起的阻塞;
    3)能够对线程有效管理(定时执行以及间隔循环执行);
Android的线程池分为4类,都是通过Executors提供的工厂方法得到线程池的具体实现是在ThreadPoolExecutor。
3.1 ThreadPoolExecutor
3.1.1 ThreadPoolExecutor的构造函数
    ThreadPoolExecutor是线程池的真正的实现,其构造方法提供一系列参数来配置线程池。

1)corePoolSize:线程池的核心线程数;
2)maximumPoolSize:线程池所容纳的最大线程数;
3)keepAliveTime:非核心线程闲置时的超时时长,超过这个时长,非核心线程被回收。
4)unit:指定keepAliveTime时间单位;
5)workQueue:线程池中的任务队列;
6)threadFactory:线程工厂,为线程池提供创建新线程的功能;
3.1.2 ThreadPoolExecutor执行任务规则
    1)如果线程池中的线程数未达到核心线程的数量,那么启动一个核心线程来执行任务;
    2)如果线程池中的线程数达到或超过核心线程的数量,这时任务会被加入到任务队列中排队等待执行;
    3)如果任务队列已满,但是线程数量未达到线程池最大值时,会立刻启动一个非核心线程来执行任务;
    4)如果步骤3中线程数量已达到线程池规定的最大值,这时会拒绝执行任务。
3.2 线程池的分类
    Android的4类线程池:FixedThreadPool;CacahedThreadPool;ScheduledThreadPool;SingleThreadPool。
3.2.1 FixedThreadPool
    通过Executors的newFixedThreadPool方法创建,特点:线程数量固定;其只有核心线程,并且核心线程没有超时限制。

3.2.2 CachedThreadPool
    通过Executors的newCachedThreadPool方法来创建;特点:线程数量不固定的线程池,而且只有非核心线程(最大线程数为Integer.MAX_VALUE)

3.2.3 ScheduledThreadPool
    通过Executors的newScheduleThreadPool方法创建;特点:核心线程数固定,非核心线程数不固定。

3.2.4 SingleThreadPool
    通过Executors的newSinglePool方法来创建;特点:只有一个核心线程。












  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值