线程池参数怎么配才不翻车

张开发
2026/4/12 0:25:58 15 分钟阅读

分享文章

线程池参数怎么配才不翻车
这篇不空谈理论直接给一套业务里能用的参数配置和代码模板。先给结论线程池配置最容易出问题的地方就三个队列无界任务堆到 OOM最大线程数乱设把机器打满拒绝策略没兜底线上直接丢任务下面我们用一套可落地模板解决它。一、先准备一个“可观测”的线程池工厂importjava.util.concurrent.*;importjava.util.concurrent.atomic.AtomicInteger;publicfinalclassBizThreadPoolFactory{privateBizThreadPoolFactory(){}publicstaticThreadPoolExecutornewIoPool(Stringname,intcore,intmax,intqueueSize){// 线程命名线上排查时能直接看出业务来源ThreadFactorythreadFactorynewThreadFactory(){privatefinalAtomicIntegeridxnewAtomicInteger(1);OverridepublicThreadnewThread(Runnabler){ThreadtnewThread(r,name-idx.getAndIncrement());t.setDaemon(false);returnt;}};// 有界队列防止任务无限堆积BlockingQueueRunnablequeuenewArrayBlockingQueue(queueSize);// CallerRunsPolicy降级回调用线程执行给上游施压而不是直接丢任务RejectedExecutionHandlerrejectHandlernewThreadPoolExecutor.CallerRunsPolicy();returnnewThreadPoolExecutor(core,max,60L,TimeUnit.SECONDS,queue,threadFactory,rejectHandler);}}二、参数怎么给1) CPU 密集型任务intcpuRuntime.getRuntime().availableProcessors();ThreadPoolExecutorpoolBizThreadPoolFactory.newIoPool(cpu-task,cpu,cpu1,200);适合压缩、加密、规则计算。2) IO 密集型任务intcpuRuntime.getRuntime().availableProcessors();ThreadPoolExecutorpoolBizThreadPoolFactory.newIoPool(io-task,cpu*2,cpu*4,1000);适合RPC、数据库、磁盘读写。三、业务代码里怎么用importjava.util.concurrent.*;publicclassOrderQueryService{privatefinalThreadPoolExecutorioPoolBizThreadPoolFactory.newIoPool(order-io,16,32,1000);publicStringqueryWithTimeout(StringorderId){FutureStringfutureioPool.submit(()-remoteCall(orderId));try{// 超时必须有不然线程会一直卡住returnfuture.get(800,TimeUnit.MILLISECONDS);}catch(TimeoutExceptione){future.cancel(true);returntimeout-fallback;}catch(Exceptione){returnerror-fallback;}}privateStringremoteCall(StringorderId){// 模拟远程调用returnok-orderId;}}四、监控必须加publicfinalclassThreadPoolMetrics{publicstaticStringsnapshot(ThreadPoolExecutorpool){returnpoolSizepool.getPoolSize(), activepool.getActiveCount(), queuepool.getQueue().size(), completedpool.getCompletedTaskCount(), taskCountpool.getTaskCount();}}定时打印或上报这几个值线上问题会好排查很多。五、优雅关闭publicstaticvoidshutdownGracefully(ThreadPoolExecutorpool){pool.shutdown();// 拒绝新任务try{if(!pool.awaitTermination(30,TimeUnit.SECONDS)){pool.shutdownNow();// 超时后强制中断}}catch(InterruptedExceptione){pool.shutdownNow();Thread.currentThread().interrupt();}}六、一个完整配置建议intcpuRuntime.getRuntime().availableProcessors();ThreadPoolExecutorbizPoolBizThreadPoolFactory.newIoPool(biz-main,Math.max(8,cpu*2),// coreMath.max(16,cpu*4),// max2000// queueSize);这套适合大多数“Web 请求 下游 IO”场景。最后总结线程池真正的稳定性来自四件事有界队列合理的 core/max可控的拒绝策略持续监控和超时兜底把这四件事做好线程池基本不会翻车。

更多文章