面试题答案
一键面试- AbortPolicy(默认策略)
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务会被拒绝,并且抛出
RejectedExecutionException
异常。这是线程池默认的拒绝策略。例如在ThreadPoolExecutor
类中,reject
方法的默认实现就是使用AbortPolicy
策略,如果任务无法被处理,就会抛出异常。 - 应用场景:适用于对任务处理非常严格,不允许任务丢失的场景。比如在一些关键的金融交易系统中,如果交易任务被拒绝意味着交易可能失败,这种情况下可以通过捕获异常进行相应的处理,如记录日志、回滚交易等操作。
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务会被拒绝,并且抛出
- CallerRunsPolicy
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务不会被拒绝,而是由提交任务的线程(调用者线程)来执行该任务。这样做的目的是减少新任务的提交速率,缓解线程池的压力。例如在
ThreadPoolExecutor
类的rejectedExecution
方法中,如果使用CallerRunsPolicy
策略,会直接在当前调用线程中执行任务r.run()
。 - 应用场景:适用于对响应时间要求不高,但希望能尽可能处理提交任务的场景。比如在一些后台日志记录系统中,即使记录日志的任务偶尔由调用线程执行,也不会对系统的主要业务逻辑产生较大影响,同时能保证日志任务尽量不丢失。
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务不会被拒绝,而是由提交任务的线程(调用者线程)来执行该任务。这样做的目的是减少新任务的提交速率,缓解线程池的压力。例如在
- DiscardPolicy
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务会被直接丢弃,不会抛出任何异常。在
ThreadPoolExecutor
类中,如果使用DiscardPolicy
策略,rejectedExecution
方法只是简单地返回,不做任何其他处理,意味着新任务被丢弃。 - 应用场景:适用于可以容忍任务丢失的场景。比如在一些实时统计系统中,对于一些时效性较强但不重要的统计数据采集任务,如果系统繁忙无法处理新任务,丢弃这些任务对整体统计结果影响不大。
- 实现原理:当有界队列已满且线程池达到最大线程数时,新提交的任务会被直接丢弃,不会抛出任何异常。在
- DiscardOldestPolicy
- 实现原理:当有界队列已满且线程池达到最大线程数时,会丢弃队列中最老的一个任务(即最先进入队列的任务),然后尝试把新提交的任务加入队列。在
ThreadPoolExecutor
类的rejectedExecution
方法中,如果使用DiscardOldestPolicy
策略,会先移除队列头部的任务(q.poll()
),然后尝试添加新任务(q.offer(r)
)。 - 应用场景:适用于希望处理较新任务的场景。比如在一些实时任务调度系统中,新的任务可能比旧任务更具有时效性和重要性,丢弃旧任务可以让系统更专注于处理最新的任务。
- 实现原理:当有界队列已满且线程池达到最大线程数时,会丢弃队列中最老的一个任务(即最先进入队列的任务),然后尝试把新提交的任务加入队列。在