目录
一. 什么是线程池
简单理解,它就是⼀个管理线程的池⼦。它帮我们管理线程,避免增加创建线程和销毁线程的资源损耗 。因为线程其实也是⼀个 对象,创建⼀个对象,需要经过类加载过程,销毁⼀个对象,需要⾛GC垃圾回收流程, 都是需要资源开销的。
二. 为什么使用线程池
1.降低资源消耗。因为线程的创建和销毁是需要在用户态和内核态之间转换。
2.提升系统响应速度。如果任务到达了,相对于从线程池拿线程,重新创建一条线程执行,速度肯定慢很多。
3.重复利用。线程用完,在放回池子,可以达到重读利用的效果,节省资源。
4.提高线程可管理性。
三. 构造器的各个参数的意义
corePoolSize:核心线程池的大小,一般是选择CPU数x2
maximumPoolSize:线程池最大容量= (⾮核⼼线程数+核⼼线程数)
keepAliveTime:空闲线程可存活时间(非核心闲置线程存活时间直接置为0)
unit:keepAliveTime的时间单位(非核心线程保持存活时间选择TimeUnit.SECONDS秒)
workQueue:存放任务的阻塞队列(使用LinkedBlockingQueue阻塞队列)
threadFactory:生产线程的工厂类
handler:饱和丢弃策略。共四种:AbortPolicy,CallerRunsPolicy,DiscardOldestPolicy
四. 线程池执行流程
五. 线程池的拒绝策略
AbortPolicy :直接抛出异常,默认使⽤此策略
CallerRunsPolicy:⽤调⽤者所在的线程来执⾏任务
DiscardOldestPolicy:丢弃阻塞队列⾥最⽼的任务,也就是队列⾥靠前的任务
DiscardPolicy :当前任务直接丢弃
六. 线程池有哪几种工作队列
- ArrayBlockingQueue:ArrayBlockingQueue(有界队列)是⼀个⽤数组实现的有界阻塞队 列,按FIFO排序量。
- LinkedBlockingQueue:LinkedBlockingQueue(可设置容量队列)是基于链表结构的阻塞 队列,按FIFO排序任务,容量可以选择进⾏设置,不设置的话,将是⼀个⽆边界的阻塞队 列,最⼤长度为Integer.MAX_VALUE,吞吐量通常要⾼于ArrayBlockingQuene; newFixedThreadPool线程池使⽤了这个队列 DelayQueue:
- DelayQueue(延迟队列)是⼀个任务定时周期的延迟执⾏的队列。根据指定 的执⾏时间从⼩到⼤排序,否则根据插⼊到队列的先后排序。newScheduledThreadPool线 程池使⽤了这个队列。
- PriorityBlockingQueue:PriorityBlockingQueue(优先级队列)是具有优先级的⽆界阻塞队列。
- SynchronousQueue:SynchronousQueue(同步队列)是⼀个不存储元素的阻塞队列,每个 插⼊操作必须等到另⼀个线程调⽤移除操作,否则插⼊操作⼀直处于阻塞状态,吞吐量通 常要⾼于LinkedBlockingQuene,newCachedThreadPool线程池使⽤了这个队列。
七. 线程池提交execute和submit有什么区别?
execute用于提交没有返回值的任务,submit()方法用于提交需要返回值的任务。线程池会返回一个future类型的对象,通过这个future对象可以判断任务是否执行成功,并且可以通过future的get()方法来获取返回值。
八. 如何关闭线程池
可以通过调⽤线程池的 shutdown 或 shutdownNow ⽅法来关闭线程池。它们的原理是遍历线 程池中的⼯作线程,然后逐个调⽤线程的interrupt⽅法来中断线程,所以⽆法响应中断的任务 可能永远⽆法终⽌。
shutdown() 将线程池状态置为shutdown,并不会⽴即停⽌:
1. 停⽌接收外部submit的任务
2. 内部正在跑的任务和队列⾥等待的任务,会执⾏完
3. 等到第⼆步完成后,才真正停⽌
shutdownNow() 将线程池状态置为stop。⼀般会⽴即停⽌,事实上不⼀定:
1. 和shutdown()⼀样,先停⽌接收外部提交的任务
2. 忽略队列⾥等待的任务
3. 尝试将正在跑的任务interrupt中断
4. 返回未执⾏的任务列表
shutdown 和shutdownnow简单来说区别如下:
shutdownNow()能⽴即停⽌线程池,正在跑的和正在等待的任务都停下了。这样做⽴即⽣ 效,但是风险也⽐较⼤。 shutdown()只是关闭了提交通道,⽤submit()是⽆效的;⽽内部的任务该怎么跑还是怎么 跑,跑完再彻底停⽌线程池。
九. 有哪几种常见的线程池
四种常见的线程池都是通过Executors创建出来的。
newFixedThreadPool:固定数目的线程池
newCachedthreadpool:可缓存线程的线程池
newSingleThreadPool:单线程线程池
newScheduledThreadPool:定时及周期执行线程池
十. 线程池异常如何处理