一、线程池有哪些,适用场景、有哪些弊端?
线程池名称 | 参数 | 适用场景 | 弊端 |
---|
newSingleThreadExecutor | (1, 1, 0,毫秒时间单位, LinkedBlockingQueue) | 适用需要串行执行的任务 | 任务会堆积在队列中,数量多的话,会造成资源不足,引起OOM |
newFixedThreadPool | (n, n, 0, 毫秒时间单位, LinkedBlockingQueue) | 适用数量固定的任务 | 任务会堆积在队列中,数量多的话,会造成资源不足,引起OOM |
newCachedThreadPool | (0, int最大值, 60, 秒时间单位, SynchronousQueue) | 适用执行时间短,数量变化多的任务 | 执行任务的线程数量最大是int的最大值,线程数量多的话,会引起OOM |
newScheduledThreadPool | —— | 适用定时、周期性的任务 | 执行任务的线程数量最大是int的最大值,线程数量多的话,会引起OOM |
二、线程池参数有哪些?
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler hander)
corePoolSize:核心线程数,指定了线程池里的线程数量
maximumPoolSize:最大线程数
keepAliveTime:超时时间,当线程数大于核心线程数,小于最大线程数,空闲的线程到了时间就会被销毁
unit: 超时时间,时间单位
workQueue:任务队列,用于存放提交但未执行的任务,有四种
threadFactory:线程工厂,用于创建线程
handler:拒绝策略,有三种
三、workQueue参数详解
SynchronousQueue:直接提交队列,无长度,提交的任务不会被存储,会被提交到新的线程执行,如果没有新的线程可以创建了,会执行拒绝策略;
ArrayBlockingQueue:有界任务队列,长度由参数指定;
LinkedBlockingQueue:无界任务队列,队列长度最大为int的最大值;
PrioriBlockingQueue:特殊的无界队列,和普通的先进先出队列不同,它是优先级高的先出;
四、hander参数详解
AbortPolocy:中止策略,该策略会抛出异常,阻止系统工作;
CallerRunsPolic:只要线程池未关闭,该策略会直接在调用者的线程中,运行被丢弃的任务,实际上任务是不丢弃的,会导致提交线程的性能急剧下降;
DisCardOledestPolicy:丢弃策略,该策略默默地丢弃无法处理的任务,不予进行处理;
我们可以实现RejectedExecutionHander接口,进行自定义策略。
五、如何自定义线程池,有什么好处?
自己可以根据需求,定义拒绝策略;
补充完善的线程信息,比如线程名,当线上出现问题时,可以根据线程名称,方便排查问题;