线程池
Android中线程形态
- AsyncTask
- HandlerThread
- IntentService
AsyncTask的原理
- AsyncTask中有两个线程池 SerialExecutor和THREAD_POOL_EXECUTOR
AsyncTask中还有一个Handler,即InternalHandler,用于将执行环境从线程池切换到主线程。AsyncTask内部就是通过InternalHandler来发送任务执行的进度以及执行结束等消息 - AsyncTask排队执行过程:系统先把参数Params封装为FutureTask对象,它相当于Runnable;接着将FutureTask交给SerialExecutor的execute方法,它先把FutureTask插入到任务队列tasks中,如果这个时候没有正在活动的AsyncTask任务,那么就会执行下一个AsyncTask任务,同时当一个AsyncTask任务执行完毕之后,AsyncTask会继续执行其他任务直到所有任务都被执行为止。
HandlerThread
HandlerThread就是一种可以使用Handler的Thread,它的实现就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就允许在HandlerThread中创建Handler了,外界可以通过Handler的消息方式通知HandlerThread执行一个具体的任务。HandlerThread的run方法是一个无限循环,因此当明确不需要再使用HandlerThread的时候,可以通过它的quit或者quitSafely方法来终止线程的执行。HandlerThread的最主要的应用场景就是用在IntentService中。
IntentService
IntentService是一个继承自Service的抽象类,要使用它就要创建它的子类。IntentService适合执行一些高优先级的后台任务,这样不容易被系统杀死。IntentService的onCreate方法中会创建HandlerThread,并使用HandlerThread的Looper来构造一个Handler对象ServiceHandler,这样通过ServiceHandler对象发送的消息最终都会在HandlerThread中执行。IntentService会将Intent封装到Message中,通过ServiceHandler发送出去,在ServiceHandler的handleMessage方法中会调用IntentService的抽象方法onHandleIntent,所以IntentService的子类都要是实现这个方法。
Android中线程池
优点:
1.重用线程,避免线程的创建和销毁带来的性能开销;
2.能有效控制线程池的最大并发数,避免大量的线程之间因互相抢占系统资源而导致的阻塞现象;
3.能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能
ThreadPoolExecutor
ThreadPoolExecutor 是线程池的真正实现,它的构造方法体统一系列的参数来配置线程池
- corePoolSize 核心线程数 cpu核心数+1
- maximumPoolSize 最大容纳线程数 2倍CPU核心+1
- keepAliveTime 非核心线程闲置超时时间
- unit
- workQueue
- threadFactory
执行任务大致遵循的原则
线程池中未达到核心线程数量,会直接启动一个核心线程
如果超过核心线程数量,任务会被添加到任务队列中排队执行
如果任务队列已满 未达到线程池最大值 会立刻启动一个非核心的线程来执行
如果线程数量达到了最大值 那么则拒绝执行该任务
分类
FixedThreadPool
一种线程数量固定的线程池,当处于空闲状态 不会被回收
CachedThreadPool
线程数量不固定,当超过60秒闲置线程会被回收
ScheduledThreadPool
核心线程数量固定管 非核心线程数量没有限制 当非核心线程空置时会被立即回收
SingleThreadPool
只有一个核心线程 任务之间不需要处理线程同步的问题