请设计一个线程池,核心要素包括线程管理、任务队列、拒绝策略和生命周期,并说明如何根据业务场景进行参数配置。
考察说明
考察候选人对线程池核心机制和设计要点的理解,以及根据实际场景进行参数配置的能力。
回答思路
- 【回答框架 1】线程池核心组件包括工作线程、任务队列(BlockingQueue)、线程工厂和拒绝策略。线程池通过复用线程减少创建和销毁开销,核心参数有corePoolSize、maximumPoolSize、keepAliveTime和workQueue。线程数估算公式为Ncpu×(1+W/C),W为等待时间,C为计算时间,实际需结合压测调整。
- 【回答框架 2】任务提交流程:先判断当前线程数是否小于corePoolSize,是则创建新线程执行任务;否则尝试将任务放入队列;若队列已满,再判断是否小于maximumPoolSize,是则创建临时线程,否则执行拒绝策略。关键点是线程池何时创建新线程、何时使用队列,边界条件需准确。
- 【回答框架 3】根据业务场景配置参数:IO密集型任务可增大线程数,CPU密集型任务线程数接近CPU核心数。队列大小影响任务等待时间和系统资源占用,有界队列配合拒绝策略更可控。拒绝策略包括AbortPolicy(默认)、CallerRunsPolicy、DiscardPolicy等,需根据对任务丢失的容忍度选择。
- 【回答框架 4】线程池生命周期管理:运行、关闭、停止等状态,通过shutdown()和shutdownNow()优雅停止,处理队列中的任务。定期监控活跃线程数、队列长度、任务拒绝次数,动态调整参数,避免资源耗尽或任务堆积。
- 【关键点 1】线程池核心组件:核心线程数、最大线程数、任务队列、拒绝策略、线程工厂。
- 【关键点 2】线程数估算公式为Ncpu×(1+W/C),最终依赖压测。
- 【关键点 3】任务提交流程:先核心线程,再队列,再最大线程,最后拒绝策略。
- 【关键点 4】队列建议使用有界队列,配合拒绝策略避免资源耗尽。
- 【关键点 5】关闭时使用shutdown()或shutdownNow(),确保任务处理完毕。
- 【易错点 1】直接使用无界队列可能导致OOM,需使用有界队列并配置拒绝策略。
- 【易错点 2】线程数设置过大或过小都会影响性能,需结合任务类型和系统资源调整。
- 【易错点 3】忽略线程池的状态管理,可能导致关闭时任务丢失或资源泄漏。