对线面试官-线程池连环问

2023-08-10 13:46:46 浏览数 (1)

面试官:线程池的底层工作原理了解吗?

派大星:当往线程池中提交任务的时候,会先判断线程池中线程数是否是核心线程数,如果小于,会创建核心线程并执行任务。如果线程数大于核心线程数,会判断阻塞队列是否已满,如果没有满,会把任务添加到阻塞队列中等待调度执行。如果阻塞队列已满,会判断线程数是否小于最大线程数,如果小于,会继续创建最大线程数并执行任务。如果线程数大于最大线程数,会执行拒绝策略,然后结束。

面试官:线程池核心配置参数是做什么的,在生产中如何配置的?

派大星:

具体核心参数说明可参考文章:对线面试官-线程池(三) 生产中如何配置可参考:对线面试官-线程池(一)

面试官:线程池的队列满了之后会发生什么

派大星:分不同情况来分析:如果配置的是非最大线程数和非无界阻塞队列的话会有以下情况:如果线程池中的队列满了并且创建的线程数达到了corePoolSize之后,会判断时候设置了maximumPoolSize这个参数如果大于coolPoolSize,此时会创建不会大于maximumPoolSize额外的线程处理队列中的请求。如果队列中的请求处理完了,额外的线程数会存活keepAliveTime时间后会自动销毁。如果队列满了,额外的线程也已经满负荷了。这个时候执行拒绝策略。工作中比较常用的是Fix(无界队列)的线程池。具体看实际的业务场景。

派大星:如果使用的是有界队列可以避免内存溢出。派大星:如果最大线程参数maxPoolSize设置的是Integer.MAX_VALUE的话,你可以无限制的不停地创建线程,一台机器上会在短时间内创建大量线程,每个线程都有自己的栈内存,占用一定的资源,会导致内存资源耗尽,系统也会崩溃,即使内存没有崩溃,也会导致机器的CPU load 负载特别高,机器也会挂掉。

面试官:在远程服务器异常的情况下,使用无界阻塞队列会不会导致内存飙升。(如果在线程池中使用无界阻塞队列会发生什么问题)

派大星:调用超时,队列会变得越来越大,此时一定会导致内存飙升起来,也有可能导致服务器OOM,内存溢出。

面试官:如果线上机器宕机,线程池中的阻塞队列中的请求怎么办

派大星:这种情况其实一定会导致线程池里积压的任务丢失的。但是可以通过在你提交一个任务到线程池里去之前,在数据库里面插入一条这个任务的信息,后续更新它的状态:未提交、已提交、已完成。提交完成之后去更新它的状态为已提交即可。系统重启之后后台线程去扫描数据库里的未提交和已提交的任务状态。可以把未提交、已提交的任务重新提交到线程池中继续执行即可

面试官:如果你配置的的有限的最大线程数量,有界队列。一旦请求过多队列打满最大线程也无法支持,应该如何去做?

派大星:可以通过自定义reject策略如果线程池无法执行更多的任务了,此时建议可以把任务信息持久化写入到磁盘里面去,后台专门启动一个线程,后续等待你的线程池的工作负荷降低了,再慢慢的从磁盘中读取之间持久化的任务,重新提交到线程池中去执行。

0 人点赞