程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

正确使用线程池的姿势,你在工作中不要只会使用默认的方式创建

balukai 2025-01-02 14:37:42 文章精选 6 ℃

背景

因为最近给同事们灌输了尽量让接口里面的方法异步化,尽量使用线程池来处理任务。所以同事们都把自己写得比较耗时的方法(一般都是一个方法里面要多次与数据库交互)改造成多线程的方式,大大的缩减了接口的响应时间。分享一下相关知识,希望能帮到对线程池不太熟悉的同学。

线程池流程

流程图


为什么使用线程池

为了提高资源利用率,复用线程,减少线程的创建与销毁的开销。

有经验的开发者,线程池一般都会选择创建固定大小。更有经验的会自己手动设置线程池的相关参数。

1 核心线程数 2 最大线程数 3 线程池中空闲线程等待工作的超时时间 4 阻塞队列类型(有界或者无界)5 拒绝策略

关于线程池大小的设置:

工作中线程数量设置多少合适?(一般计算密集型线程池大小设置为CPU个数,IO密集型的任务线程池大小设置为CPU个数的2N+1)。 最好的方式是通过压力测试来实验。



任务过多的处理

任务超出了线程总数后怎么拒绝?

系统给出的四种策略:

1 直接丢弃(就像和女朋友没有告别的分手)

2 丢弃抛出异常(给女朋友分手找个理由,也是默认的拒绝策略)

? 3 丢弃最早的任务(喜新厌旧)

? 4 由调用线程(提交任务的线程)直接执行此任务

? 可能存在的风险:任务会交给上层线程(主线程)执行,导致上层线程既要处理其他任务,又要忙碌处理线程池的源源不断的任务,导致悬挂,进而导致线上故障。

? 自定义的拒绝策略

将任务信息放入消息队列中 (不放弃任务一个任务)


核心线程会被回收吗

默认不会,如果设置成会的话,超过keepAliveTime后一样会像非核心线程一样被回收,但是这样就失去了线程池设计的初衷,即为了复用线程。

写在最后

即便使用池化技术,也只是提高了线程池内的线程利用率,但在高并发的业务场景中,池化技术一样会带来性能和资源开销的问题。如果我们使用消息组件来执行异步业务,则可以在性能和资源两者之间做一个很好的平衡.

Tags:

最近发表
标签列表