龙空技术网

【面试真题】线程池拒绝策略

兔子六号 102

前言:

现时我们对“多线程拒绝策略怎么解决问题”可能比较珍视,咱们都需要学习一些“多线程拒绝策略怎么解决问题”的相关文章。那么小编也在网摘上网罗了一些关于“多线程拒绝策略怎么解决问题””的相关知识,希望同学们能喜欢,大家一起来学习一下吧!

当请求过多,超出线程池负荷的时候,会触发拒绝策略。下列选项中,对于拒绝策略的描述错误的是( ):

A、CallerRunsPolicy,线程调用运行该任务的 execute 本身,此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。

B、AbortPolicy,处理程序遭到拒绝将直接抛出异常,丢弃任务。

C、DiscardPolicy,不能执行的任务将被删除。这种策略将丢弃任务,同时也会抛出异常。

D、DiscardOldestPolicy,如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序。

解析

线程池工作中,当任务量很大,超过系统实际承载能力时,如果不去搭理它,系统很可能崩溃,所以jdk内置提供了四种线程池的拒绝策略,可以合理解决这种问题。当线程池中线程已用完不能再创建,等待队列也排满,如果此时再有新任务,就会触发执行拒绝策略之一。

CallerRunsPolicy(调用者运行策略)

一般在不允许失败的、对性能要求不高、并发量较小的场景下使用,因为线程池一般情况下不会关闭,也就是提交的任务一定会被运行,但是由于是调用者线程自己执行的,当多次提交任务时,就会阻塞后续任务执行,性能和效率自然就慢了。当触发拒绝策略时,只要线程池没有关闭,就由提交任务的当前线程处理。

所以选项A是正确的。

AbortPolicy(中止策略)

当触发拒绝策略时,它就会直接抛出拒绝执行的异常,中止策略就是直接打断当前执行的流程。ThreadPoolExecutor中默认的策略就是AbortPolicy,ExecutorService接口的系列ThreadPoolExecutor因为都没有显示的设置拒绝策略,所以默认的都是这个。但是请注意,ExecutorService中的线程池实例队列都是无界的,也就是说把内存撑爆了都不会触发拒绝策略。当自己自定义线程池实例时,使用这个策略一定要处理好触发策略时抛的异常,因为他会打断当前的执行流程。

所以选项B是正确的。

DiscardPolicy(丢弃策略)

如果你提交的任务无关紧要,你就可以使用它 。因为它就是个空实现,会悄无声息的吞噬你的的任务。它就是直接静悄悄的丢弃这个任务,不触发任何动作。所以这个策略基本上不用了。

所以选项C是错误的,因为它不会触发任何动作,也不会抛出异常。

DiscardOldestPolicy(弃老策略)

这个策略依然会丢弃任务,丢弃时也是无声无息,但丢弃的是老的未执行的任务,而且是待执行优先级较高的任务。此拒绝策略,是一种喜新厌旧的拒绝策略。是否要采用此种拒绝策略,还得根据实际业务是否允许丢弃老任务来认真衡量。

所以选项D是正确的。

因此这道题的正确答案应该是C。

标签: #多线程拒绝策略怎么解决问题 #线程池执行任务失败怎么重新提交任务信息错误