线程池
任务多,任务简单,为了减少频繁创建销毁线程开销
可以使用线程池,预先创建一部分线程,重复使用,减少创建销毁开销
在 JDK5 版本中增加了内置线程池实现 ThreadPoolExecutor
public class ThreadPoolExecutor extends AbstractExecutorService{
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHander hander);
}
有七个参数:
- corePoolSize:核心线程数量(不会被销毁)
1)prestartAllCoreThreads()或者 prestartCoreThread()方法,预先创建核心数量个线程
2)起初不创建,有任务到达时创建,直到达到核心数量个线程
- maximumPoolSize:最大线程数量
- keepAliveTime:超出核心数量部分的线程,在没有任务时执行,空闲多久后销毁
- unit: keepAliveTime 的时间单位
TimmeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
工imeUnit.SECONDS; //秒
TimmeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
- workQueue:一个阻塞队列,用来存储等待执行的任务
- threadFactory:线程工厂,主要用来创建线程
- handler:表示当拒绝处理任务时的策略
线程池的执行流程
- 如果线程池中存活的核心线程数小于线程数 corePoolSize 时,线程池会创建一个核心线程去处理提交的任务。
- 如果线程池核心线程数已满,即线程数已经等于 corePoolSize,一个新提的任务,会被放进任务队列 workQueue 排队等待执行。
- 当线程池里面存活的线程数已经等于 corePoolSize 了,并且任务队列workQueue 也满,判断线程数是否达到 maximumPoolSize,即最大线程数是否已满,如果没到达,创建一个非核心线程执行提交的任务。
- 如果当前的线程数达到了 maximumPoolSize,还有新的任务过来的话,直接采用拒绝策略处理
线程池中的队列
- ArrayBlockingQueue:有界队列,是一个用数组实现的有界阻塞队列,按 FIFO排序量。
- LinkedBlockingQueue:可设置容量队列,基于链表结构的阻塞队列,按 FIFO排序任务,容量可以选择进行设置,不设置的话,将是一个无边界的阻塞队列,最大长度为 Integer.MAX_VALUE,吞吐量通常要高于 ArrayBlockingQuene;newFixedThreadPool 线程池使用了这个队列。
- DelayQueue:延迟队列,是一个任务定时周期的延迟执行的队列。根据指定的执 行 时 间 从 小 到 大 排 序 , 否 则 根 据 插 入 到 队 列 的 先 后 排 序 。newScheduledThreadPool 线程池使用了这个队列
- PriorityBlockingQueue:优先级队列,是具有优先级的无界阻塞队列
- SynchronousQueue:同步队列,一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于 LinkedBlockingQuene,newCachedThreadPool 线程池使用了这个队列
线程池的拒绝策略
- AbortPolicy 策略:该策略会直接抛出异常,阻止系统正常工作
- CallerRunsPolicy 策略:只要线程池未关闭,该策略直接在调用者线程中,运行当前的被丢弃的任务
- DiscardOleddestPolicy 策略:该策略将丢弃最老的一个请求,也就是即将被执行的任务,并尝试再次提交当前任务
- DiscardPolicy 策略:该策略默默的丢弃无法处理的任务,不予任何处理
execute 与 submit 的区别
execute 适用于不需要关注返回值的场景,submit 方法适用于需要关注返回值的场景
关闭线程池
shutdownNow 和 shutdown 两个方法
shutdownNow:对正在执行的任务全部发出 interrupt(),停止执行,对还未开始执行的任务全部取消,并且返回还没开始的任务列表。
shutdownNow:对正在执行的任务全部发出 interrupt(),停止执行,对还未开始执行的任务全部取消,并且返回还没开始的任务列表。
shutdown:当我们调用 shutdown 后,线程池将不再接受新的任务,但也不会去强制终止已经提交或者正在执行中的任务