如何合理配置线程池

1、根据“任务的性质”分析

1.1、CPU 密集型任务

解释:和内存打交道,大量计算。例如大数的计算,正则匹配

如何配置:

  1. CPU 密集型任务应配置尽可能小的线程,如配置 Ncpu+1 个线程的线程池(Ncpu 是处理器的核的数目),这样留一个空出来,用来做切换。
  2. 如果线程太多,会造成线程在CPU内部的上下文切换。CPU的线程上下文切换比指令执行耗时的更多。

1.2、IO 密集型任务

解释:和磁盘,网络,文件,数据库交互很多的。

如何配置:由于 IO 密集型任务线程并不是一直在执行任务,在操作的时间,是不消耗CPU的。不会经常在CPU内切换线程上下文,则应配置尽可能多的线程,如 2*Ncpu。

注意:对于 IO 型的任务的最佳线程数,有个公式可以计算 Nthreads = NCPU * UCPU * (1 + W/C)

NCPU 是处理器的核的数量

UCPU 是期望CPU 利用率(应该介于 0 和 1 之间)

W/C 是等待时间与计算时间的比率,等待时间与计算时间在 linux 下可以使用 vmstat 或top 等命令查看

1.3、混合任务

解释:前两者的混合

如何配置:如果可以拆分,将其拆分成一个 CPU 密集型任务和一个 IO 密集型任务。

  • 只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐 量将高于串行执行的吞吐量。
  • 如果这两个任务执行时间相差太大(例如:一个是常量时间,一个是正无穷),则没必要进行分解。
  • 可以通过 Runtime.getRuntime().availableProcessors()方法获得当前设备的 CPU 个数。

2、根据“任务的优先级”分析

优先级不同的任务可以使用优先级队列 PriorityBlockingQueue 来处理。它可 以让优先级高的任务先执行。

3、根据“任务的执行时间”分析

执行时间不同的任务可以交给不同规模的线程池来处理,或者可以使用优先 级队列,让执行时间短的任务先执行。

4、根据“任务的依赖性(依赖数据库连接)”分析

依赖数据库连接池的任务,因为线程􏰀交 SQL 后需要等待数据库返回结果, 等待的时间越长,则 CPU 空闲时间就越长,那么线程数应该设置得越大,这样 才能更好地利用 CPU。

5、建议使用有界队列

有界队列能增加系统的稳定性和预警能力,可以根据需 要设大一点儿,比如几千。

假设,我们现在有一个 Web 系统,里面使用了线程池来处理业务,在某些 情况下,系统里后台任务线程池的队列和线程池全满了,不断抛出抛弃任务的异 常,通过排查发现是数据库出现了问题,导致执行 SQL 变得非常缓慢,因为后台 任务线程池里的任务全是需要向数据库查询和插入数据的,所以导致线程池里的 工作线程全部阻塞,任务积压在线程池里。

如果当时我们设置成无界队列,那么线程池的队列就会越来越多,有可能会 撑满内存,导致整个系统不可用,而不只是后台任务出现问题。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值