Android的线程和线程池

主线程与子线程

主线程:UI线程(作用:运行四大组件以及处理它们和用户的交互)
子线程:执行耗时任务,比如:网络请求,I/O操作等

Android中的线程形态

  • AsyncTask(串行执行)
    轻量的异步任务类,可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新UI。
    AsyncTask封装了Thread和Handler

public abstract class AsyncTask<Params, Progress, Result>

4个核心方法:
onPreExecute() : 在主线程中执行,在异步任务执行之前,此方法会被调用,一般可以用于做一些准备工作;
doInBackground(Params…params) : 在线程池中执行,此方法用于执行异步任务,此方法通过publishProgress()方法来更新任务的进度,publishProgress()会调用onProgressUpdate().该方法需要返回计算结果给onPostExecute();
onProgressUpdate(Progress…values) : 在主线程中执行, 当后台任务的执行进度发生改变时此方法会被调用;
onPostExecute(Result result) : 在主线程中执行,在异步任务执行之后,此方法被调用,其中result参数是后台任务的返回值,即doInBackground的返回值;
其他方法:
onCancelled() : 异步任务取消,不会调用onPostExecute()
使用限制:
1) 必须在主线程中加载;

2)AsyncTask的对象必须在主线程中创建

3)execute方法必须在UI线程调用

4) 一个AsyncTask对象只能执行一次,即只能调用一次execute方法

5)不要在程序中直接调用onPreExecute(), onPostExecute, doInBackground和onProgressUpdate()

注意:
1)4.1以上版本,调用execute()是串行执行
2) 并行执行:executeOnExecutor()方法

  • HandlerThread
    继承自Thread, 它是一种可以使用Handler的Thread。
    HandlerThread与普通的Thread不同之处在于,其在内部创建了消息队列,外界需要通过Handler的消息方式来通知HandlerThread来执行一个具体的任务。
    使用场景:IntentService
    注意:由于HandelrThread的run()是一个无限循环,可通过quit或者quitSafely来终止线程的执行;
  • IntentService
    是一种特殊的Service,继承自Service并且是一个抽象类。可用于执行后台耗时的任务,当任务执行后它会自动停止;由于其是Service,所以它的优先级比单纯的线程要高;
    实现上,封装了HandlerThread和Handler
    注意:由于每次执行一个后台任务就必须启动一次IntentService,而IntentService内部则通过消息的方式向HandlerThread请求执行任务,Handler中的Looper是顺序处理消息的。这意味着IntentService也是顺序执行后台任务的。
  • 线程池
    优点:
    1)重用线程池,避免因为线程的创建和销毁所带来的性能开销;
    2) 能有效控制线程池的最大并发数,避免大量的线程之间互相抢占系统资源而导致阻塞现象
    3) 能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能
    介绍:
    来源于JAVA的Executor,是一个接口,真正线程池的实现ThreadPoolExecutor,它提供了一系列的参数来配置线程池;

ThreadPoolExecutor :
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue workQueue,
ThreadFactory threadFactory)

corePoolSize: 线程池的核心线程数,一直存活,即使处于闲置状态;可设置超时状态(allowCoreThreadTimeOut),时间间隔由keepAliveTime所指定;
maximumPoolSize: 最大线程数,当活动线程数达到这个数值后,后续的新任务将会被阻塞;
keepAliveTime: 非核心线程闲置时的超时时长,超过这个时长,非核心的线程就会被回收;
unit: keepAliveTime的时间单位
workQueue: 线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中;
threadFactory: 线程工厂,为线程池提供创建新线程的功能。ThreadFactory是一个接口,它只有一个方法:Thread newThread(Runnable r);
ThreadPoolExecutor执行任务大致遵循的规则
1. 若线程池中的线程数量未达到核心线程数量,直接启动一个核心线程来执行任务;
2. 若线程池中的线程数量已经达到或者超过核心线程数量,那么任务会被插入到任务队列中等待执行;
3. 如果在2)中无法将任务插入到任务队列,大多是由于任务队列已满,若线程数量未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务;
4. 若3)中的线程数量已经达到线程池规定的最大值,那么就拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者;
分类
总共四类: FixedThreadPool 、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor
FixedThreadPool
创建方式: Executors.newFixedThreadPool
只有核心线程并且核心线程不会被回收,可以快速的相应外界的请求,任务队列无大小限制;
在这里插入图片描述
CachedThreadPool
创建方式: Executors.newCachedThreadPool
线程数量不确定,其最大的线程数量为Integer.MAX_VALUE,只有非核心线程;CachedThreadPool的任务队列是SynchronousQueue,相当于空集合,导致任何任务都会被立即执行;适合执行大量的耗时较少的任务;
在这里插入图片描述
ScheduledThreadPool
创建方式: Executors.newScheduledThreadPool
核心线程数量固定,非核心线程数量是Integer.MAX_VALUE,当非核心线程闲置时会被立即回收,适合于执行定时任务和具有固定周期的重复任务;
在这里插入图片描述
SingleThreadExecutor
创建方式: Executors.newSingleThreadExecutor
只有一个核心线程,确保所有的任务都在同一个线程中按顺序执行,意义在于统一所有的外界的任务到一个线程中,使得所有的任务之间不需要处理线程同步的问题;
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值