线程池继承体系
1. 继承关系
2. 相关说明
Executor
- Executor是“执行者”接口,用来执行任务。Executor提供了execute()接口来执行已提交的Runnable任务的对象。
- Executor是为了将“任务提交”与“任务如何运行”分离开的机制。
ExecutorService
- ExecutorService继承于Executor,它是“执行者服务”接口。
AbstractExecutorService
- 实现了ExecutorService接口,存在的目的是为ExecutorService接口提供默认实现。
ThreadPoolExecutor
- 继承于AbstractExecutorService是线程池的实现类。
ScheduledThreadPoolExecutor
- 创建线程池ThreadPoolExecutor在构造方法的配置参数说明:
- corePoolSize:在线程池中始终维护的线程个数。
- maxPoolSize:在corePooSize已满、队列也满的情况下,扩充线程⾄此值。
- keepAliveTime/TimeUnit:maxPoolSize 中的空闲线程,销毁所需要的时间,总线程数收缩回corePoolSize。
- blockingQueue:线程池所⽤的队列类型。
- threadFactory:线程创建⼯⼚,可以⾃定义,有默认值 Executors.defaultThreadFactory() 。
- RejectedExecutionHandler:corePoolSize已满,队列已满,maxPoolSize 已满,最后的拒绝策略。
2. 拒绝策略
- AbortPolicy:这种拒绝策略在拒绝任务时,会直接抛出一个类型为 RejectedExecutionException 的 RuntimeException,让你感知到任务被拒绝了,于是你便可以根据业务逻辑选择重试或者放弃提交等策略。
- DiscardPolicy:这种拒绝策略正如它的名字所描述的一样,当新任务被提交后直接被丢弃掉,也不会给你任何的通知,相对而言存在一定的风险,因为我们提交的时候根本不知道这个任务会被丢弃,可能造成数据丢失。
- DiscardOldestPolicy:如果线程池没被关闭且没有能力执行,则会丢弃任务队列中的头结点,通常是存活时间最长的任务,这种策略与第二种不同之处在于它丢弃的不是最新提交的,而是队列中存活时间最长的,这样就可以腾出空间给新提交的任务,但同理它也存在一定的数据丢失风险。
- CallerRunsPolicy:相对而言它就比较完善了,当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。
3. Executors
newCachedThreadPool()
- 创建一个不限制线程数量的线程池。
- 方法将corePoolSize设置成0,将maximumPoolSize设置为Integer.MAX_VALUE。
- 使用的SysnchronousQueue阻塞队列,来了任务就创建线程,线程空闲超过60秒就销毁线程。
newSingleThreadExecutor()
- 创建只有一个线程的线程池。
- 方法将corePoolSize和maximumPoolSize都设置成1。
- 使用的LinkedBlockingQueue阻塞队列。
newFixedThreadPool()
- 创建固定大小的线程池
- 方法创建的线程池corePoolSize和maximumPoolSize是相等的。
- 使用的LinkedBlockingQueue阻塞队列。
newScheduledThreadPool()