-
为什么要设计线程池?有什么好处?
- 使用线程池可以重用线程,减少创建、销毁线程带来的开销。起初是来一个客户端,创建一个线程,再进行销毁,这是很浪费资源的。线程池中的线程由服务器预先创建,来一个客户端,从线程池中为其分配一个线程,使用完不销毁。
- 使用线程池可以有效控制线程的数量,方便线程管理。
- 并发处理用户的请求,提高响应用户的速度。
-
线程池是如何实现的?
-
创建一个有最大线程数和最大请求队列长度的线程池,把线程设置为脱离状态,这样在线程结束时不会占用系统资源,并初始化一个信号量和互斥锁
-
当有新任务到达时,先检查队列是否满,随后将其加入工作队列,信号量被触发,通知工作线程有新任务到达
-
每个工作线程都会调用worker方法,该方法内部调用run执行任务,run在一个循环中运行,收到信号量通知,加上互斥锁,并从队头取一个任务,执行该任务,执行完释放互斥锁,等待下一个任务,直到线程池被停止
-
当线程池不再使用时,会设置停止标志位通知工作线程停止工作,等待所有工作线程结束后,释放工作队列和线程数组占用的内存
-
-
互斥锁为什么要配合条件变量一起使用?
-
互斥锁保证了在某一时刻只能有一个线程访问同一变量
-
条件变量允许线程在特定条件不满足的时候挂起,直到条件变量为真,为了防止检查条件与挂起线程之间会有竞态发生,互斥锁常常配合条件变量一起使用
-
-
线程池中的工作线程有怎样的工作模式?一直处于等待状态吗?
-
线程池中的工作线程是处于一直阻塞等待的模式下的
-
线程池中的工作线程在初始化后会进入一个循环
-
先检查条件变量,随后释放互斥锁并检查工作队列,工作队列为空解锁,不为空则从工作队列中弹出一个任务,互斥锁解锁,处理任务
-
-
线程池中的线程数量是根据什么确定的?
- 这里的线程数量是根据CPU的数量确定,通常来说,线程池的大小可以设置为与CPU核心数相同或者稍微多一点,以确保CPU资源得到充分利用
-
设置线程池大小的依据原则、把线程池大小设置越大越好吗?
-
如果需要处理大量的并发请求,可能需要一个较大的线程池来快速响应这些请求
-
但并不是越大越好。
-
每个线程都会占用一定的内存资源。如果线程数设置得太多,可能会导致系统内存不足。
-
管理大量线程会带来额外的开销,包括上下文切换、调度等
-
-
-
你的线程池工作线程处理完一个任务后的状态是什么?
-
如果处理完任务后,请求队列为空,没有要处理的任务时,这个线程就重新回到阻塞等待的状态
-
如果处理完任务后,请求队列不为空,代表还有要处理的任务,那么这个线程就处于与其他线程竞争资源的状态
-
-
如果同时1000个客户端进行访问请求,线程数不多,怎么能及时响应处理每一个呢?
-
客户端的请求被封装为任务,并提交到线程池的工作队列中
-
可以考虑增加线程数、优化任务执行时间
-
-
线程池有什么改进的空间吗?
-
线程池的大小在创建时确定,且无法动态调整。可以引入一个动态调整线程数的机制,比如设置任务队列长度的阈值、根据CPU利用率调整线程数、基于内存(内存使用接近上限则避免增加线程数)、基于任务执行时间(任务执行时间过长增加线程数以加快处理速度)
-
当前的任务队列是无优先级的,所有任务按照先进先出(FIFO)的顺序处理。如果某些任务更加紧急或重要,可以考虑引入优先级队列
-
web server线程池相关面试题
![](https://img-home.csdnimg.cn/images/20240711042549.png)