首先 理解线程池 7大参数
- ①. corePoolSize:线程池中的常驻核心线程数
在创建了线程池后,当有请求任务来之后,就会安排池中的线程去执行请求任务,近似理解为今日执勤线程也就是 常驻线程数量
当线程池中的线程数目达到corePoolSize指定数量后,就会把最新到达的任务放入到阻塞队列即缓存队列当中.
-
②. maximumPoolSize:线程池能够容纳同时执行的最大线程数,此值必须大于等于1
-
③. keepAliveTime:多余的空闲线程存活时间,当空间时间达到keepAliveTime值时,多余的线程会被销毁直到只剩下corePoolSize个线程为止(非核心线程)
-
④. unit:keepAliveTime的单位 即 TimeUnit 类
-
⑤. workQueue:任务队列即阻塞队列,被提交但尚未被执行的任务(候客区)
-
⑥. threadFactory:线程工厂,用于生成 线程池里的工作线程,一般用默认即可
-
⑦. handler:拒绝策略,表示当线程队列满了并且工作线程大于等于线程池的最大线程数(maxnumPoolSize)时如何来拒绝
jdk里 线程池的策略
1 在执行创建对象的时候不会立即创建线程,而是创建线程的时候调用execute()才会创建,
2 此时任务进入 线程池会做如下判断:
2.1 如果正在运行的线程数量小干corePoolSize,那么马上创建线程运行这个任务:
2.2 如果正在运行的线程数量大干或等干 corePoolSize,那么将这个任务放入阻塞队列中。
2.3 如果这时候队列满了,在往外扩容线程,但扩容线程不能大于最大线程数,然后会执行最新进来的任务
2.4 如果队列满了目正在运行的线程数量大于最大线程数 maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。
3.当一个线程完成任务时,它会从队列中取下一个任务来执行。
4.当一个线程无事可做超过一定的时间(keepAliveTime)时,线程池会判断:
如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。
线程池的拒绝策略
①. 等待队列也已经排满了,再也塞不下新的任务了。同时,线程池的maximumPoolSize也到达了,无法接续为新任务服务,这时我们需要拒绝策略机制合理的处理这个问题
②. JDK内置的拒绝策略
AbortPolicy(默认):直接抛出RejectedException异常阻止系统正常运行
CallerRunsPolicy:"调用者运行"一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是返回给调用者进行处理
DiscardOldestPolicy:将最早进入队列的任务删除,之后再尝试加入队列
DiscardPolicy:直接丢弃任务,不予任何处理也不抛出异常.如果允许任务丢失,这是最好的拒绝策略
③. 以上内置策略均实现了RejectExecutionHandler接口
在阿里巴巴开发手册提到
解决方案
https://blog.youkuaiyun.com/m0_71149992/article/details/125367753