Java 线程池简要-自定义线程池
自定义线程池
直接看源码,自定义线程池的几个关键参数
|
|
几个核心参数:
- corePoolSize - 即时空闲也会保持的核心线程数量
- maximumPoolSize - 池中最大线程数量
- keepAliveTime - 超过核心数量后,等待接收任务的最大时间
- unit - keepAliveTime 参数的单位
- workQueue - 执行之前排队的缓存队列
- handler - 线程数和队列数都达到最大值后的处理器
新任务来了之后的流程
直接看javadoc怎么说的,已经很详细了:
核心数和最大线程数:
ThreadPoolExecutor会根据核心线程数和最大线程数不断调整线程池大小。
当新的任务通过 execute()方法提交后:- 当前线程数 < corePoolSize : 会创建一个新线程处理请求,即时有其他的空闲线程
- 当前线程数 > corePoolSize 但是队列还没满 -> 任务加入队列
队列如果也满了,并且当前线程数 < maximumPoolSize : 创建一个新线程处理请求 - corePoolSize = maximumPoolSize : 固定大小的线程池
- maximumPoolSize = Integer.MAX_VALUE,线程池处理任意数量的并发任务
一般来说,core 和 maximum 的值是构造的时候指定,但也可以通过方法动态调整
按需创建
默认的话即时核心前程也是有新任务的时候才创建,但是可以通过方法覆盖此策略。创建新的线程
通过 ThreadFactory 创建新的线程,不指定就用默认的。
创建的线程有相同的 ThreadGroup,优先级,都是非守护线程的状态。
提供一个不同的 ThreadFactory ,即可修改这些策略。Keep-alive 时间
超过 corePoolSize 的时候,如果有空闲线程,那边就会被终结。之后有需求会重新创建Queuing
任何的 BlockingQueue 都可以用来传递、持有提交的任务。- 小于 corePoolSize ,创建新线程,不加到队列
- 大于 corePoolSize , 总是加入队列而不是创建新线程
- 如果无法加入队列,创建新线程直到达到 maximumPoolSize。超过了则任务被拒
主要有3种加入队列的策略: - SynchronousQueue (待补充)
- LinkedBlockingQueue (待补充)
- ArrayBlockingQueue (待补充)
拒绝任务
线程池已经关闭 or 队列和线程全部饱和,会触发任务拒绝处理,默认有4个预置策略- 抛出运行时异常(默认)
- 发起execute线程自己执行任务
- 直接扔掉
- 扔掉最早的任务
钩子方法
开始和结束执行任务时提供钩子方法。可以做一些:初始化ThreadLocal,统计,加日志等队列维护
终结