- 队列小了容易引发拒绝
- 队列大了线程数不会扩容。 扩容的瞬间会导致性能抖动;
- 固定线程则抢占资源, 对大部分时候的指标不友好。
- 任务队列满了之后,新提交的任务会短时间内触发大量的线程创建操作。 这种现象叫什么,有什么专业术语?
- 有没有发现,线程池这么搞,比较落后,只适合N年前的应用模式?
在同一个Java应用中存在多个线程池, 为了应对突然到来的大量并发请求, 线程池中的线程数需要根据 queue 中堆积的任务数量进行自动扩容。
我们只需要根据等待队列的容量, 动态增长核心线程数即可。 ThreadPoolExecutor#setCorePoolSize()
实例方法会自动处理其余的事情;
线程池参数
一个 Builder? 维护最初始的参数:
- 初始核心线程数
- 初始最大线程数
- 队列高水位线(capacity)
- 队列低水位线
- 步长; 或者是自动计算; 最初时保持一定的比例关系;
例如: (高水位线 - 低水位线)/ (最大线程 - 初始核心线程 + 当前线程数) ?
AdapterSizeThreadPoolQueue
自动根据 corePoolSize, maxPoolSize, 以及 queue.size 来进行处理, 以确定是否需要:
- 内部包装一个queue;
- 自动增加或者减少corePoolSize;
- 每积累到一定的queue数量,就增加 corePoolSize;
还有一种思路是到一定数量就拒绝一次以刺激threadpool增长 cache数量,但是并不太安全。 增加和维护核心线程数更靠谱一些。而且这个是阻塞式的queue。
扩容或者缩容时, 需要使用原子计数器, 并吃掉能处理的异常。
- 动态线程池(Hippo4J): https://github.com/acmenlt/dynamic-threadpool
- 线程池实时管理与监控工具的实现与思考: https://www.jianshu.com/p/6f6e2bcb8128
- 通过micrometer实时监控线程池的各项指标: https://cloud.tencent.com/developer/article/1650102
- 惊群效应: https://www.zhangbj.com/p/768.html