【踩坑笔记】--论如何合理的使用线程池

本文讲述了线程池在提升系统并发能力中的重要性,通过一个线上问题引出线程池设置不合理导致的性能下降。讨论了线程池的原理,强调合理设置线程池大小、选择合适的拒绝策略和等待队列的重要性。并提供了一个计算线程池大小的公式,以及对不同拒绝策略和等待队列类型的分析。
摘要由CSDN通过智能技术生成

1.背景

  如果说如何提升系统的并发能力,大家第一想到的肯定是采用多线程,而提到多线程编程,就不得不说到线程池,合理的使用线程池可以帮助我们大大提升系统的性能,但前提是“合理”两字,如果乱用/滥用线程池,带来的可能不是高性能而是灾难了。最近在一个需求当中,因为涉及到多方调用,自然而然的想到了使用线程池来提升性能,但由于线程池数量设置的不合理,导致在系统负载很低的情况下出现了线程阻塞的问题,不但没有提高接口的性能,反而让接口被线程池拖挂了。问题发生后,针对这一问题做了复盘,趁此机会也对线程池的原理和使用做了一番探究,记录在此,避免后续再犯同样的错误。

2.线程和线程池的原理

  俗话说知己知彼,才能百战百胜,要想使用好线程池,必须要知道线程和线程池的原理,这部分知识已经在网上已经有大量的资料,我这边就不再赘述,这里放上2篇我认为写的比较好的关于线程和线程池的文章。

编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程

深入理解Java线程池:ThreadPoolExecutor

3.合理使用线程池

   基于第二部分的知识,我们知道线程是一种稀缺的资源,频繁的创建销毁线程会大大降低系统的性能,所以才有了线程池来解决这个问题(池化的思想其实是一种通用的解决方案,用于解决一些资源创建耗费高昂,但又需要多次重复使用的问题,如数据库连接池)。线程池虽然解决了线程频繁创建销毁的问题,但他并不是解决多线程问题的银弹,必须要合理使用线程池,才能发挥线程池最大的功效,否则很可能适得其反,下面是我总结的一些关于合理使用线程池的点。

3.1设置线程池的大小

   合理设置线程池大小很重要,前面提到的线上问题就是因为没有合理设置线程池大小才发生的,之所以要使用线程池就是因为线程是一种耗费较高的资源,我们既不能在系统中无限创建线程,那样会导致系统资源枯竭,也不能创建过少的线程,那样会导致无法充分利用CPU资源。

设置线程池大小的问题也属于老生长谈了,网上一搜索就会有各种各样的文章博客,这里就参考《java concurrency in practice》这本书做个总结吧。

  1. 合理的设置线程池大小取决于任务的类型,针对于计算密集型的任务,一般设置N+1个线程(N指CPU的核数,理想情况下设置N个线程是对CPU使用的效率最高的,但是即使是计算密集型的任务,也有可能因为一些其他原因中断导致线程切换,所以额外设置一个线程)
  2. 如果是IO密集型或者存在阻塞操作的任务,则需要设置大一点的线程数,有一些博客上会写到IO密集型设置2N+1的线程数,其实是不正确的,实际上针对IO密集的任务,需要看真正的线程CPU使用时间和线程等待时间的比例,书中给了一个公式:给定N=CPU的核数,U=目标CPU使用率(0<=U<=1),W/C = 线程等待时间/线程CPU使用时间。一个合理的线程池数量=N * U * ( 1 + W/C)。

    我们在开发过程中遇到的最多的IO密集型任务就是远程接口调用了,一般来说,远程接口调用,W/C的比例一般在9以上,即

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值