Android线程池
优点
- 重用线池中的线程,避免因为线程的创建和销毁所带来的性能开销
- 能有效控制线程池的最大并发数,避免大量的线程之间因为互抢系统资源而导致的阻塞现象
- 能够对线程进行简单的管理,并提供定时执行以及指定间隔循环执行等功能
创建一个线程池需要的参数:
- corePoolSize 核心线程数大小。当提交一个任务时,如果当前线程数小于corePoolSize,就会创建一个线程。即使其他有可用的空闲线程。
- runnableTaskQueue(任务队列):用于保存等待执行的任务的阻塞队列。 可以选择以下几个阻塞队列
(1) ArrayBlockingQueue:是一个基于数组结构的有界阻塞队列,此队列按 FIFO(先进先出)原则对元素进行排序。
(2) LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO (先进先出) 排序元素,吞吐量通常要高于ArrayBlockingQueue。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
(3)SynchronousQueue:一个不存储元素的阻塞队列。每个插入操作必须等上一个元素被移除之后,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
(4)PriorityBlockingQueue:一个具有优先级的无限阻塞队列。 - 不同的runnableTaskQueue对线程池运行逻辑有很大影响
- maximumPoolSize(线程池最大大小):线程池允许创建的最大线程数。如果队列满了,并且已创建的线程数小于最大线程数,则线程池会再创建新的线程执行任务。值得注意的是如果使用了无界的任务队列这个参数就没什么效果。
构造函数
public ThreadPoolExecutor(
int corePoolSize, //线程池的核心线程数
int maximumPoolSize,//线程池容纳的最大线程数
long keepAliveTime, //非核心线程闲置时的超时时长
TimeUnit unit, //用于指定keepAliveTime参数的时间单位
BlockingQueue<Runnable> workQueue, //线程池的任务队列
ThreadFactory threadFactory //线程工厂,为线程池提供创建新线程的功能
)
ThreadPoolExector执行任务时大致规则如下:
- 如果线程池的线程数量为达到核心线程数量,那么会直接启动一个核心线程执行任务
- 如果线程池线程数量达到了或者超过了核心线程数量,那么任务会被插入到任务队列中排队等待执行
- 如果上一步骤无法将任务插入到任务队列中,这是因为任务队列已经满了,如果线程数量未达到线程池规定的最大值时,会立即启动一个非核心线程来执行任务.
- 如果上一步骤中的线程数量已经达到了线程池规定的最大数量,那么就拒绝执行此任务,会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者.
AsyncTask对线程池的配置:
- 核心线程数等于CPU核心数+1
- 线程池的最大线程数为CPU核心数的2bei4+1
- 核心线程无超时机制,非核心线程在闲置时的超时时间为1秒
- 任务队列的容量为128
线程池的分类
1.FixedThreadPool
- 线程数量固定的线程池,线程处于空闲状态的时候,他们不会被回收,除非线程池被关闭了
- 只有核心线程数,并且不会被回收
- 没有超时机制
- 任务队列没有大小限制
- 能够快速的对外界的请求作出响应
2.CacheThreadPool
- 线程数量不固定的线程池,最大线程数为Integer.MAX_VALUE(很大的数)
- 只有非核心线程
- 有超时机制,超时60秒闲置线程就会被回收
- 任务队列相当于一个空集合,任何任务都被立即执行
- 适合执行大量的耗时较少的任务
3.ScheduledThreadPool
- 核心线程数量固定的,非核心线程数没有限制的
- 非核心线程数闲置的时候会被立即回收
- 主要用于执行定时任务和具有固定周期的重复任务
4.SingleThreadPool
- 只有一个核心线程数
- 保证任务都在同一个线程中按顺序执行
- 不需要处理线程同步的问题