(面试经典问题之线程池篇)线程池构成、作用及其基本原理详解

一、线程池的定义

线程池是一种管理和复用线程的技术,通过维护一定数量的线程来执行任务,从而避免频繁创建和销毁线程,提升系统性能,特别是在高并发场景下。它提供线程复用、任务排队和线程管理等功能。

更精简的说:线程池是维持管理固定数量线程的池式结构。

除了线程池之外,其他的池式结构还包括:数据库连接池、内存池、对象池等,他们的共同点都是复用资源,后续文章会对这些池也进行深入讲解,这是后话。

二、线程池的作用

精简来说,线程池的作用分为两点:

1、性能优化:不过度占用核心线程,异步执行耗时任务;

2、并发执行:充分利用cpu多核,并发执行核心线程;

三、为什么需要线程池?

之所以需要线程池,就是为了利用线程池的作用,去解决一些特定问题。

当某类任务特别耗时,严重影响核心线程(也称作生产者线程,读者若有不明白什么是生产者线程的,可以自行去搜索一下生产者线程-消费者线程模型,该点自学不难理解,下面有不明白的名词也是同理)处理其他任务时,可以将该任务切换到线程池中的其他线程中异步执行,从而避免了核心线程的阻塞,让核心线程可以继续执行其他任务。

其中,耗时任务可以分为耗时等待和耗时处理两种类型。耗时等待任务一般也可以称作I/O密集型任务,比如网络I/O收发数据时可能需要等待内核中的接收缓冲区和发送缓冲区就绪,才能执行对应操作,这便是耗时等待任务。耗时处理任务一般也可以称作cpu密集型任务,比如某种需要大量运算的任务,需要极大的占用cpu运行时间,这便是耗时处理任务。以上两种任务统称为耗时任务,线程池就是需要去异步执行这类任务。

四、为什么需要维持管理固定数量的线程?

不知读者看完前三节是否也会产生相同的问题,前面聊线程池作用时,都在突出一个点,就是“当核心线程执行到某耗时任务时,将该任务切换到其他线程去异步执行”,那为什么不到那时候再创建一个新线程,而是要一直维持管理固定数量的线程呢?

这个问题的答案很明确:为了避免线程频繁的创建和销毁。我们不能当需要一个新线程时才创建它,等用完了就去销毁它,这会导致系统资源的极大浪费,并且创建线程属于系统调用,是一个相对耗时的操作,会影响高并发场景下的系统性能。因此,线程池的概念才应运而生,我们早早就初始化一个线程池,里面维护着固定数量的线程,当有需要的时候可以自行去池里拿,用完后也不必销毁,而是放回池中供别的任务使用。

那就又出现一个新的问题:线程池中的线程数量是不是越多越好?答案也很明确,并不是越多越好。因为系统资源是有限的,随着线程数量的持续增加,反而会带来系统负担,降低性能。通俗将就是我池子里10个线程就够用了,你非要维护20个,那不是还要多付他们工资嘛,跟互联网公司裁员的道理也大差不差。

那究竟应该维持多少数量的线程呢?这个问题的答案是根据经验公式来的,分为两类。1、当我们的耗时任务是cpu密集型时,线程数量=cpu核心数;2、当我们的耗时任务时I/O密集型时,线程数量=(线程等待时间+cpu运算时间)*cpu核心数/cpu运算时间;具体为什么等于这些值,读者可以自行去搜索答案,这里不赘述。

五、线程池的构成

上文提到,线程池的应用场景在于有一个生产者线程(该线程不属于线程池中线程)发布耗时任务,然后消费者线程(这些线程是线程池中的线程)取出任务并执行任务。这便是生产者-消费者模型的大体框架,但凡涉及到这个框架,我们就需要一个队列去存储任务,在这里也称作任务队列。

因此,线程池的结构如下图所示(截自mark老师的树状图):

有关线程池的基本原理就介绍到这,后续将进行其他池式组件的介绍。

https://github.com/0voice

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值