拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Java面试被问线程池,答对这5点就够了

Java面试被问线程池,答对这5点就够了

线程池是Java并发编程的核心,也是面试中几乎必问的考点。很多人能背出七大参数,却说不清执行流程、拒绝策略和调优思路。其实面试官想考察的无非是这5个关键点,答对了基本就能过关。

第1点:七大参数与执行流程

线程池的核心构造参数有七个:corePoolSize(核心线程数)、maximumPoolSize(最大线程数)、keepAliveTime(空闲存活时间)、unit(时间单位)、workQueue(工作队列)、threadFactory(线程工厂)、handler(拒绝策略)。

执行流程是面试必问:提交任务时,若当前线程数小于核心线程数,直接创建核心线程执行;若核心线程已满,任务进入工作队列;若队列已满且线程数小于最大线程数,创建非核心线程;若线程数达到最大且队列也满,触发拒绝策略。

关键点:核心线程默认不会回收,除非设置allowCoreThreadTimeOut(true)。非核心线程空闲超过keepAliveTime后销毁。

第2点:四种拒绝策略及选择

当线程池无法接收新任务时,由拒绝策略处理。JDK提供四种:

AbortPolicy(默认):抛出RejectedExecutionException,调用方需捕获处理,适合关键业务。

CallerRunsPolicy:由提交任务的线程自己执行,能降低提交速度,形成负反馈,适合不允许丢任务的场景。

DiscardPolicy:静默丢弃,不抛异常,风险高,仅适合无关紧要的任务。

DiscardOldestPolicy:丢弃队列中最旧的任务,再尝试提交,可能丢失重要任务。

面试加分:实际项目中建议自定义拒绝策略,记录日志并报警,避免任务无声丢失。

第3点:线程池状态与关闭

线程池有五种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。状态流转是理解关闭行为的关键。

shutdown():状态变为SHUTDOWN,不再接收新任务,但会执行完队列中已有任务。shutdownNow():状态变为STOP,不再接收新任务,尝试中断正在执行的任务,并返回队列中未执行的任务列表。

注意:shutdownNow()不保证立即停止,需要任务响应中断。生产环境关闭线程池时,通常先shutdown(),等待一段时间后再shutdownNow(),并配合awaitTermination。

第4点:线程数设置与队列选择

线程数设置没有银弹,取决于任务类型:

CPU密集型:线程数 ≈ CPU核数 + 1,减少上下文切换。

IO密集型:线程数 ≈ CPU核数 × (1 + 平均等待时间/平均计算时间),通常可设为核数的2倍以上。

队列选择同样关键。LinkedBlockingQueue默认无界,容易堆积任务导致OOM;ArrayBlockingQueue有界,更安全;SynchronousQueue不存储任务,直接移交,适合高吞吐场景。最佳实践:使用有界队列,并配合合理的拒绝策略,防止资源耗尽。

第5点:异常处理与监控

execute()提交的任务若抛出异常,会直接打印到控制台,且线程可能终止;submit()会捕获异常并封装到Future中,只有调用get()才会抛出。因此,推荐使用submit()并处理Future,或在任务内部用try-catch兜底。

监控方面,关注核心指标:活跃线程数、队列大小、已完成任务数、拒绝任务数。可通过ThreadPoolExecutor的getter方法获取,并接入Micrometer或Prometheus。自定义ThreadFactory给线程命名,便于排查问题。

总结

面试回答线程池,按这5点展开即可:参数与流程、拒绝策略、状态与关闭、线程数与队列、异常与监控。如果能结合业务场景说明选型理由,比如“订单系统用CallerRunsPolicy保证不丢单”,就能让面试官看到你的实战经验。线程池不是配置完就万事大吉,持续监控和动态调优才是高手与普通人的分水岭。

返回列表