线程池传递对象参数_关于线程池相关参数问题

又是喜闻乐见的生产事故环节,不过这次是隔壁项目组的,看了一眼事故原因大概就比较清楚了

3fde4ec5dfbee86283536d240f2d5a90.png

大致情况是在线程池的操作中,没有添加异常策略,导致采用了默认的线程池拒绝策略抛出异常,影响了程序的执行

参数简单介绍一下

public 
  • corePoolSize 线程池中的核心线程数,不受运行时间限制,只要线程池在运行就会保持这个线程的运行
  • maximumPoolSize 线程池最大线程数
  • keepAliveTime 存活时间,超出核心线程数的线程在超出这个时间后会进行回收
  • TimeUnit 存活时间的单位
  • workQueue 执行队列,在任务进入到线程池的线程中执行前,会放到这个队列中,
  • threadFactory 用来创建线程的工厂方法,里面也只有一个new Thread的接口方法,可以对加入线程池的线程进行统一处理比如命名等,如下所示
public 

可以看到,线程名称已经做了调整

f631c50abd30032eb7d4cbb460b09c20.png
  • handler:最后就是这次问题的原因,因为线程池中如果不添加拒绝策略的构造器,采用的是默认的拒绝策略,直接抛出异常
public 

这个defaultHandler其实就是AbortPolicy

public 

直接就报错了,在隔壁业务逻辑下是显然不合理的,可以看一下线程池的执行逻辑

public 

在添加到队列失败的时候会进行reject方法,然后调用拒绝策略的rejectedExecution方法,有以下几个策略方案

b681cf217e63c6c6ee3994aed6d89d07.png

CallerRunsPolicy

AbortPolicy 是直接抛出异常的已经说过了,看一下第二个CallerRunsPolicy,该策略方案为,在当前线程池未关闭的情况下,直接在当前线程Runnable中执行调用

public 

比如上文中的线程池参数调整一下,限制队列长度为3,采用该策略执行进行执行

ThreadPoolExecutor 

发生了一件很魔法的事,明明是顺序队列,但是打印出来的结果却发生了变化,不仅顺序颠倒,而且TestThreadFactory的命名也发生了变化,就是因为后来的线程在当前线程”插队”导致的

a318e26736dc0596218f3f737e25711f.png

DiscardOldestPolicy

该方法会在线程塞满队列后踢出最早的线程e.getQueue().poll()并将当前任务添加进队列

public 

DiscardPolicy

这个就直接无视掉溢出的任务了。。。目前隔壁业务组采用的这个方案,我觉得是不太合理的。。因为会导致关联的业务获取数据不准确

public 

RejectedExecutionHandler

其实我认为如果业务逻辑比较独特的话,自定义是比较合理的拒绝策略,上文也可以看出所有的拒绝策略都是实现了RejectedExecutionHandler这个接口来进行的,对我们而言,如果是必要的情况下,可以适当在拒绝策略里进行逻辑调整,比如放到缓存,或者数据库,然后通过定时任务的情况来进行更新,如下

public 

我们在执行时,如果出现该情况,会进行自定义拒绝策略的方案

7bf94af3983e2c8dc98b2e42c8f7eb65.png

给个别同事吱了一声。。希望隔壁项目组数据不会丢太多

1ce32ed7f7649579332eb0d3991754e5.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值