647 字
3 分钟
线程池如何实现参数的动态修改?

线程池如何实现参数的动态修改?#

线程池提供了几个 setter 方法来设置线程池的参数。 JDK 线程池参数设置接口来源参考[7] 这里主要有两个思路: image.png

  • 在我们微服务的架构下,可以利用配置中心如 Nacos、Apollo 等等,也可以自己开发配置中心。业务服务读取线程池配置,获取相应的线程池实例来修改线程池的参数。
  • 如果限制了配置中心的使用,也可以自己去扩展ThreadPoolExecutor,重写方法,监听线程池参数变化,来动态修改线程池参数。

62.线程池在使用的时候需要注意什么#

2024 年 03 月 16 日增补 我认为比较重要的关注点有 3 个: ①、选择合适的线程池大小

  • 过小的线程池可能会导致任务一直在排队
  • 过大的线程池可能会导致大家都在竞争 CPU 资源,增加上下文切换的开销

可以根据业务是 IO 密集型还是 CPU 密集型来选择线程池大小:

  • CPU 密集型:指的是任务主要使用来进行大量的计算,没有什么导致线程阻塞。一般这种场景的线程数设置为 CPU 核心数+1。
  • IO 密集型:当执行任务需要大量的 io,比如磁盘 io,网络 io,可能会存在大量的阻塞,所以在 IO 密集型任务中使用多线程可以大大地加速任务的处理。一般线程数设置为 2*CPU 核心数。

②、任务队列的选择

  • 使用有界队列可以避免资源耗尽的风险,但是可能会导致任务被拒绝
  • 使用无界队列虽然可以避免任务被拒绝,但是可能会导致内存耗尽

一般需要设置有界队列的大小,比如 LinkedBlockingQueue 在构造的时候可以传入参数来限制队列中任务数据的大小,这样就不会因为无限往队列中扔任务导致系统的 oom。 ③、尽量使用自定义的线程池,而不是使用 Executors 创建的线程池,因为 newFixedThreadPool 线程池由于使用了 LinkedBlockingQueue,队列的容量默认无限大,实际使用中出现任务过多时会导致内存溢出;newCachedThreadPool 线程池由于核心线程数无限大,当任务过多的时候会导致创建大量的线程,可能机器负载过高导致服务宕机。

线程池如何实现参数的动态修改?
作者
强人自传
发布于
2024-04-29
许可协议
CC BY-NC-SA 4.0