线程池问题解读

线上同事写的线程池

private static ThreadFactory pushThreadFactory  = new ThreadFactoryBuilder().setNameFormat("event-redirect-%d").build();
private static ThreadPoolExecutor appPushExecutor = new ThreadPoolExecutor(8, 16,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(),pushThreadFactory, new ThreadPoolExecutor.AbortPolicy());

 

场景解读:

处理微信回调事件,采用了上图异步线程处理的方式,然后异步线程处理调用了一个很耗时的接口,大概5到10s。

到了高峰期的时候,发现,微信回调一直超时,超过了微信回调等待时间5秒

问题分析:


ThreadPoolExecutor线程池中各参数解读

corePoolSize:核心线程池大小

maximumPoolSize :最大线程池大小(当阻塞队列满了,才会扩大到最大线程池大小)

keepAliveTime :线程最大空闲时间

unitTimeUnit :时间单位

BlockingQueue<Runnable> workQueue ::线程等待队列

ThreadFactory threadFactory: 线程创建工厂

RejectedExecutionHandler handler :拒绝策略

所以根据参数配置可以分析:阻塞队列用到了new LinkedBlockingQueue<>(),默认的队列大小是Integer的最大值,等同于无界队列,也就是线程永远接近只有8个,不会扩大到16个,

导致了高峰期回调都阻塞在队列中,随着内存飙升,应用进行fullGc,处理缓慢,超过了微信的回调5秒限制。

20210317233604481.png

 

解决方案:

根据业务场景:我们调整如下

private static ThreadFactory pushThreadFactory  = new ThreadFactoryBuilder().setNameFormat("event-redirect-%d").build();
private static ThreadPoolExecutor appPushExecutor = new ThreadPoolExecutor(32, 64,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(5000),pushThreadFactory, new ThreadPoolExecutor.AbortPolicy());

 

调整说明:因为耗时的是io操作,所以我们大概按4核,cpu核数/0.1=40调整为64

如果是cpu密集型的,才应该设置得跟cpu接近的核数。
 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值