线程池的定义和运行逻辑
多线程的问题:
如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。
那么一个很自然的想法就出现了,如果能有一种技术使得线程可以复用,即执行完一个任务,并不被销毁,而是可以继续去执行其他任务就好了。
就此,线程池技术应运而生。
线程池的运行逻辑如下:
- 作为一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
- 线程池线程都是后台线程。
- 每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。
- 如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池会自动添加另一个辅助线程,以确保所有处理器都保持繁忙状态。这样可以更有效地利用系统资源,提高并发处理能力。
- 如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程,但线程的数目永远不会超过最大值。
- 超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。
线程池的组成部分主要分为3个部分,这三部分配合工作得到一个完整的线程池:
- 任务队列,存储需要处理的任务,由工作的线程来处理这些任务
- 通过线程池提供的API函数,将一个待处理的任务添加到任务队列,或者从任务队列中删除。
- 已处理的任务会被从任务队列中删除
- 线程池的使用者,也就是调用线程池函数往任务队列中添加任务的线程就是生产者线程。
- 工作的线程(任务队列任务的消费者),N个
- 线程池中维护了一定数量的工作线程, 他们的作用是是不停的读任务队列, 从里边取出任务并处理。
- 工作的线程相当于是任务队列的消费者角色。
- 如果任务队列为空,工作的线程将会被阻塞(使用条件变量/信号量阻塞)
- 如果阻塞之后有了新的任务,由生产者将阻塞接触,工作线程开始工作。
- 管理者线程(不处理任务队列中的任务),1个
- 特的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测。
- 当任务过多的时候,可以适当的创建一些新的工作线程(消费者)
- 当任务过少的时候,可以适当的销毁一些工作的线程。
- 特的任务是周期性的对任务队列中的任务数量以及处于忙状态的工作线程个数进行检测。