线程池拒绝策略引发的灵异事件

作者因使用线程池工具类处理跑批任务时出现数据未更新问题,经排查发现是线程池拒绝策略为DiscardPolicy导致任务被丢弃。作者重申了四种线程池拒绝策略,并给出三种解决方案,即改成无界队列、将拒绝策略改成CallerRunsPolicy、走队列慢慢消费,作者采用了第二种方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自从昨天的一波bug吃了亏,我决定狠狠的总结一番线程池的拒绝策略

bug回顾:

我昨天在跑批,读取文件中的流水信息更新账单,量也还好,大概几万单吧,为了快点我就直接用我现成的一个线程池的工具类开多个线程跑,通过关注日志,发现怎么没过多久就跑完了。我一开始就以为就是处理的比较快,但是我昨天统计实收实付的时候发现怎么还这么多数据未实收实付,一开始看了很多单发现还好,但逐渐往后看怎么modified time都不太对呀,感觉像没有更新到。

此时,我重新修改了日志信息,新增了统计,就拿刚刚的重新跑了一遍,发现怎么只跑了1W多就停了。服务也没有跪,异常信息也没有,一切很自然的中断了。我第一反应是不是自己异常处理的有问题,把异常吃掉了,检查完发现也没啥问题。

那就纳闷了,就算量大把内存撑爆了也该报错呀,这啥都好好的。 因为本身这部分逻辑本身也不太复杂,逐行回看代码的时候,一个线程池的工具类吸引了我的注意。我点进去一看配置,核心线程配的5, 最大线程 50 , 阻塞队列 10000 ,拒绝策略是DiscardPolicy(丢弃任务且不抛弃异常) 看完我简直要哭了呀!

怪不得每次跑到1W多点就没掉了,任务插入的速度太快了,一开始核心线程沾满了,就开始插入10000条到队列,这时候还在疯狂插入任务,且没有线程空闲,只能继续增加线程到最大线程数50,依旧没有线程空闲,且任务仍在不断插入,所以后续的任务全部被直接丢弃了。

第一条,就是我要重申一遍,四种拒绝策略,巩固一下:

  • AbortPolicy  丢弃任务,抛出异常
  • DiscardPolicy 丢弃任务,且不抛出异常
  • DiscardOldestPolicy 丢弃队列最前面的,接入最新的(喜新厌旧)
  • CallerRunsPolicy  阻塞,由调用线程处理该任务

然后我想说,

不要贪方便,随便用别人的线程池,充分考虑自己的场景进行线程池的相关配置。

其实回过头来看,我最初用的那个线程池是不是有点限流的意思!

那么问题来了,这个问题怎么改会比较好?

方案一,改成无界队列

方案二:拒绝策略改成CallerRunsPolicy 

方案三: 走队列,慢慢消费(比如mq,让多实例消费)

我是用的第二种,第一种我怕把内存撑爆了,第二种阻塞我觉得我能接受,问题不大。  期待评论区的最佳方案,哈哈哈哈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白衣神棍

大爷,看的满意就赏个子呗!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值