写本文的目的就是作为学习笔记,内容大部分参考网上资料
一.线程池基本原理
在传统服务器结构中, 常是有一个总的监听线程监听有没有新的用户连接服务器, 每当有一个新的用户进入, 服务器就开启一个新的线程用户处理这个用户的数据包。这个线程只服务于这个用户 , 当用户与服务器端关闭连接以后, 服务器端销毁这个线程。
对于少量用户的情况来说,上述方法足够满足需求;但当我们在大量用户的情况下,我们将面临大量消息频繁请求服务器;在这种情况下,服务器频繁地开辟与销毁线程极大地占用了系统的资源,创建与销毁线程都已经成为一种奢侈的开销,系统为了开辟和销毁线程将浪费大量的时间和资源。
线程池提供了一个解决外部大量用户与服务器有限资源的矛盾, 线程池和传统的一个用户对应一个线程的处理方法不同, 它的基本思想就是在程序开始时就在内存中开辟一些线程, 线程的数目是固定的,他们独自形成一个类, 屏蔽了对外的操作, 而服务器只需要将任务交给线程池就可以了。
当有新的客户请求到达时 , 不是新创建一个线程为其服务 , 而是从“池子”中选择一个空闲的线程为新的客户请求服务 ,服务完毕后 , 线程进入空闲状态。如果没有线程空闲的话, 就将任务暂时积累 ,等待线程池内有线程空闲以后再进行处理。
通过对多个任务复用已经存在的线程对象 , 降低了对线程对象创建和销毁的开销。当客户请求时 , 线程对象已经存在 , 可以提高请求的响应时间 , 从而整体地提高了系统服务的表现。
二. 线程池主要组成部分:
1)线程数组:线程数组实际上是在线程池初始化时开辟的一段存放一堆线程tid的空间,在逻辑上形成一个池,里面放置着提前创建的线程tid;这段空间中包含了正在工作的线程,等待工作的线程(空闲线程),等待被销毁的线程,申明但没有初始化的线程空间。
核心线程:实际执行任务的线程
2)任务队列:用来存放没有处理的任务(实际上存放的是任务接口),提供一种缓冲机制,实现这种结构有好几种方法,常用的是队列,主要运用先进先出原理,另外一种是链表之类的数据结构,可以动态的为它分配内存空间,应用中比较灵活。
任务接口:任务抽象出来形成的接口,每个任务必须实现的接口,当线程池的任务队列中有可执行任务时,被空闲的工作线程调去执行。把任务抽象出来形成接口,可以做到线程池与具体的任务无关。
3)线程管理者:作为线程池的管理者,该线程的主要功能包括:检查线程池内线程的存活状态,工作状态;负责根据服务器当前的请求状态去动态的增加或删除线程,保证线程池中的线程数量与任务量维持在一个合理高效的平衡上;说到底,它就是一个单独的线程,定时的去检查,根据我们的一个维持平衡算法去增删线程。
线程池整体结构与工作流程