Spring Boot中如何配置线程池拒绝策略,妥善处理好溢出的任务

SpringBoot线程池配置拒绝策略: 默认情况下会忽略异常,并且并不适合所有场景。
内置策略:抛出异常、忽略任务、忽略最旧的以及运行调用者。
自定义策略:继承RejectedExecutionHandler实现。
项目:电子商务订单处理,2 02 0 年推出。

你自己掂量一下。

线程的拒绝策略有哪些

不幸的是,当谈到线程池拒绝策略时,我实际上在这方面有一些经验。
好吧,我们来谈谈这四种策略。

AbortPolicy,这是默认的取消策略。
这是什么意思?也就是说,当你向线程池添加任务时,任务队列就满了,池中的线程也很忙。
此时,如果你想添加任务,抱歉,线程池会直接给你抛出RejectedExecutionException。
这相当于直言不讳地说:“不,你等着,我在这里完成我的工作。
”这种方法虽然简单,但是显然是有问题的,会导致系统无法处理新的请求。

我们来谈谈CallerRunsPolicy,这个策略有点像“我帮你分担负载”。
任务队列也已满,线程池中没有空闲线程。
此时,被拒绝的任务将直接由提交任务的线程执行。
看起来任务并没有失败,但问题出现了。
任务调度线程可能被阻塞,影响系统性能。
不过,这种策略非常适合您想要减慢任务提交过程并稳定系统的情况。

然后是 DiscardOldestPolicy。
这个策略有点像“旧的不去,新的不来”。
任务队列已满,线程池没有空闲线程。
此时,线程池会首先查看队列中最早的任务,然后将其移除,然后尝试提交当前被拒绝的任务。
此策略适用于您想要消除最旧的任务并让新任务首先出现的情况。
但问题也很明显,一些重要的旧任务可能会丢失。

最后,丢弃策略。
这个策略简单粗暴。
它直接删除被拒绝的任务,而不执行任何操作或引发异常。
这适用于对消除某些任务不敏感或在系统负载较高时不需要处理所有任务的情况。
但问题也随之而来,一些重要的任务可能被忽视。

事实上,除了这四种策略之外,您还可以自定义您的退出策略。
例如,实现 RejectedExecutionHandler 接口、日志记录或请求任务。

综上所述,这四种拒绝策略各有其适用场合。
您选择哪一种取决于您的业务需求。
说实话,当时我不太明白,但是后来我明白了。

java线程池有什么拒绝策略

上周遇到一个项目,Java线程池配置错误。
要知道,线程池拒绝策略很重要。

2 02 3 年4 月,朋友的项目中,选择了AbortPolicy,结果任务过多时抛出异常。
特点是明确拒绝,处理严格,但异常必须处理,否则任务就会丢失。

我朋友后来觉得这个不行,就改成了DiscardPolicy,结果丢了很多任务。
简单有效,但数据会丢失,无法用于非关键业务。

然后我再次尝试DiscardOldestPolicy,但是最旧的任务丢失了,并且重新提交了新的任务。
重要的任务可能会丢失,但某些任务是允许延迟的。

最后他们决定使用 CallerRunsPolicy 将任务返回给调用者执行。
避免任务丢失,但可能会影响调用者线程的性能。

综上所述,AbortPolicy严格,DiscardPolicy和DiscardOldestPolicy容忍损失,CallerRunsPolicy平衡稳定性和性能。
您必须根据业务需求进行选择,同时考虑对任务丢失的敏感度、系统容错能力和性能要求。
就看你了,这部分具体业务场景我不太清楚。
别打扰。

线程池有哪 4 种拒绝策略?

你问了一个非常专业的问题。
我已经经历过线程池领域的陷阱,所以我会给你一些细节。

记得有一年冬天,我在杭州做一个电商项目的时候,服务器差点被挂掉。
如果线程池配置不正确,新任务提交后就会立即崩溃,整个系统就会卡死。
因此,线程池的拒绝策略确实需要仔细考虑。

你提到的四种方法我都在项目中用过,每种方法都有自己的陷阱:
1 . AbortPolicy:这是最直接的方法。
如果无法提交新任务,将直接向您抛出 RejectedExecutionException。
我设置的时候,半夜接到运维来电,系统崩溃了,都是因为这个异常。
后来我在代码中添加了catch异常。
如果作业被拒绝,请先记录,然后重试提交。
但采用这种策略,你必须容忍这种异常,否则程序会变得混乱。
适合任务不能丢失,但需要知道哪个环节出现问题的场景。

2 DiscardPolicy:这个策略是最简单粗暴的。
新的作业会被毫无疑问地直接拒绝。
有一年我建立了一个日志管理系统。
工作量非常大,队列满了,所以我就采用了这个策略。
结果呢?有几次遇到关键日志没有处理的情况,后来发现日志系统有几分钟的延迟。
因此,采用这种策略,您必须确保丢失任务不会致命。
适合任务丢失也没关系的场景,比如计算一些临时数据。

3 DiscardOldestPolicy:这比 DiscardPolicy 稍好一些。
当队列满时,最早的任务被丢弃,新的任务可以进入。
很多年前我建立了一个短信推送系统。
我在工作量大的时候用过这个,发现系统稳定性好很多。
但也有陷阱。
有时你可能会放弃一项非常重要的任务。
适用于可以接受任务丢失但必须保证新任务安全的场景。

4 CallerRunsPolicy:这个策略是最离谱的。
如果无法发送新任务,则发送该任务的线程将被允许自行发送。
有一年我在做一个监控系统,工作量非常大。
我使用了这个策略。
结果,所有提交任务的线程都很忙,系统吞吐量上升。
然而,也有一些陷阱。
发送任务的线程太忙,其他任务可能没有机会执行。
适用于任务不能丢失,但需要控制系统负载的场景。

关于触发线程池拒绝策略的两种情况,举个栗子:

主动关闭线程池:有一年我在搭建一个定时任务系统,半夜想关闭系统。
结果还是有新的任务提交,却被断然拒绝,系统就炸了。
后来我改成先暂停任务提交,然后关闭线程池就可以了。

资源饱和:有一年我在做一个高并发的系统,任务量突然急剧增加。
核心线程全部用完,队列已满,新任务被直接拒绝。
后来我增加了核心线程数并扩展了队列,一切都很好。

我给你一些策略选择建议:

任务不能丢失:使用CallerRunsPolicy,但是你要控制提交线程的负载。

必须知道任务已被拒绝:使用AbortPolicy,但它必须能够处理异常。

只要任务完成就可以了丢失:使用DiscardPolicy或DiscardOldestPolicy,但必须考虑风险。

总之,线程池如果使用得当的话可以省去很多麻烦,但是如果使用得不正确的话真的会让你夜不能寐。
希望我的经验可以帮到你。