一、前言
学完了高并发,我们就得认识线程池,在我们服务器与客户端建立连接后,处理业务都是有线程来完成的,这就遇到一个问题,正常情况下一个app面对的的用户是上万甚至百万不等,那么这么多用户服务器处理业务开线程岂不是要开上万百万?显然这不现实,这开销系统资源太大了,硬件设备根本承受不了,而线程池就是用来解决这一问题。
二、什么是线程池
1.概念:
线程池顾名思义,也就是把线程放在一个地方进行集中管理,特别的是,线程池会有预先创建好的最小线程数,线程池在任务还没有到来之前,创建一定数量(N)的线程,放入空闲队列中。这些线程都是处于阻塞(Suspended)状态,不消耗CPU,但占用较小的内存空间。
当新任务到来时,缓冲池选择一个空闲线程,把任务传入此线程中运行;如果缓冲池已经没有空闲线程,则新建若干个线程。当系统比较空闲时,大部分线程都一直处于暂停状态,线程池自动销毁一部分线程,回收系统资源。
2.优点:
1.减少系统资源消耗:与普通的线程使用相比较,我们服务器要是接入一个用户就开一个线程,用户一多这开销巨大,而线程池则是开好一定线程数,做业务时这些线程进行重复使用,在高并发的情况下,优势就明显了。
2.提高相应速度:因为少了创建线程这一步骤,任务到达时,无需等待线程创建即可立即执行。
3.提高线程的可管理性:线程池的可拓展性使得我们可以自己加入新的功能,比如说定时、延时来执行某些线程。
二、线程池组成
线程池的设计有很多,每个人设计出来都会不太一样,那么比较经典的结构有三个队列的结构,还有个只有任务队列的这种结构,这里要介绍的是三队列的结构。
三个队列:任务队列、空闲队列、忙碌队列
1.任务队列:用到的是queue类型,实现先进先出,业务的处理必须是按先后来执行,不然就乱套了。
2.空闲队列:用的是list链表,一个空闲队列初始有多个空闲线程。
3.忙碌队列:用的也是list链表,空闲队列的线程处理业务就来到忙碌队列。
图示:
执行流程:
一有业务,业务进入到任务队列--------任务唤醒空闲队列的一个线程,此时这个线程进入到忙碌队列,业务完成,线程离开忙碌队列,回到空闲队列。
空闲队列空了时:还有未处理任务,开辟新的线程进行处理,此线程为临时线程
忙碌队列为空时:且空闲队列大于最小线程数,也没有业务要处理,此时会把多的临时线程销毁。
要注意的是:三个队列的执行有先后,多线程访问公有的资源时就存在线程同步问题,所以在使用时要在公共资源加锁,使用互斥量。