异常内容如下
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@174a9357 rejected from java.util.concurrent.ThreadPoolExecutor@68ab7098[Running, pool size = 160, active threads = 160, queued tasks = 10000, completed tasks = 588179]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at com.test.TcpServerHandler.channelRead(TcpServerHandler.java:71)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
线程池配置如下
new ThreadPoolExecutor(processNum * 10, processNum * 10, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(10000), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy())
服务器是8核16线程的
异常后重启一段时间还是会重现,每次都是 completed tasks = 588179 这个数字时抛异常,哪位大神有解决方案,求指教
答案:根据你的线程池参数配置,抛出这个exception是正确的。抛异常原因是待处理任务数量到达了配置的10000个(new LinkedBlockingQueue(10000)),这时候再来一个待处理的任务,根据你配置的拒绝策略(new ThreadPoolExecutor.AbortPolicy()),这时候,就回抛出题中的异常。
解决办法:方向一:你这个任务明显是耗时任务,考虑加入mq或者数据库先把待处理的任务记录到db,慢慢处理,替换线程池的方案。
方向二:判断任务耗时是否正常,可否优化耗时时间,减少任务堆积。
根据给出的内容,线程池还在running,但是pool已经满了(160),然后queue也满了(10000),所以新submit的task被abort策略拒绝了...
看比例,160运行:10000等待,说明单个任务执行时间太长了,处理不过来了...
每次都是 completed tasks = 588179 这个数字时抛异常
这可能说明你每个任务的执行时间都很恒定,所以导致每次到这个时候(588179+160+10000),线程池就满了。
我建议首先检查一下任务的处理逻辑,看看代码有没有什么问题(之前遇到过线程任务里面有大循环的,有sleep的,有互相锁数据的,有调用长耗时三方接口的),打日志,观察单个任务的执行时间,优化代码的耗时,或者从业务角度调整相关逻辑...
然后还可以加mq一类的消息队列做消费端接耦,实在不行就加资源,加线程,加硬件...
1万的队列都扛不住,你的那些任务是有多耗时
这个帖子可以看看:https://blog.csdn.net/wzy_1988/article/details/38922449
解决方案:
尽量调大maximumPoolSize,例如设置为Integer.MAX_VALUE
public ExecutorService customerExecutorService = new ThreadPoolExecutor(3, Integer.MAX_VALUE, 0, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>());
使用其他排队策略,例如LinkedBlockingQueue
<span style="white-space:pre"> </span>public ExecutorService customerExecutorService = new ThreadPoolExecutor(3, 5, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
java.util.concurrent.RejectedExecutionException
这个异常是在任务无法由Executor
执行时抛出的。这通常是因为Executor
已经被关闭,或者因为它的任务队列已经满了。
目测不是配置问题,就是堆积的任务太多了处理不过来了
new LinkedBlockingQueue(10000) 最大积压10000个任务
new ThreadPoolExecutor.AbortPolicy() 积压满了就拒绝服务
解决方案:
改善积压情况
提高容量
这个异常是触发了线程池的拒绝策略导致的, 你需要大致了解一下线程池的线程调度逻辑。
线程池中有几个核心参数:
提交的任务将先使用核心线程数, 但超过核心线程数, 则存入等待队列中, 当等待队列满了, 则创建小于等于最大线程数的线程执行任务, 当最大线程数也不足以容纳新的任务时将出发拒绝策略。
可用的拒绝策略有:
本文向大家介绍Java线程池的几种实现方法及常见问题解答,包括了Java线程池的几种实现方法及常见问题解答的使用技巧和注意事项,需要的朋友参考一下 工作中,经常会涉及到线程。比如有些任务,经常会交与线程去异步执行。抑或服务端程序为每个请求单独建立一个线程处理任务。线程之外的,比如我们用的数据库连接。这些创建销毁或者打开关闭的操作,非常影响系统性能。所以,“池”的用处就凸显出来了。 1. 为什么要使
问题内容: 我只是在查看Python FAQ,因为它是另一个问题中提到的。以前从未真正详细地研究过它,我遇到了一个问题:“例外情况有多快?”: try / except块非常有效。实际上捕获异常是昂贵的。在2.0之前的Python版本中,通常使用以下习惯用法: 我对 “捕获异常代价高昂”这一 部分感到有些惊讶。这是否仅是指您实际上将异常保存在变量中的情况,或者通常是所有s(包括上面示例中的一个)的
抛出异常的行为是否可能抛出不同的异常? 为了抛出异常,必须(可选地)分配新对象,并调用其构造函数(隐式调用fillinstacktrace)。在某些情况下,听起来像addSupressed也被称为。那么如果没有足够的内存会发生什么呢?JVM是否需要预分配内置异常?例如,(1/0)会抛出OutOfMemoryError而不是ArithmeticException吗? 此外,构造函数是一个方法调用,因
我试图用spring配置bitronix,但我在启动Tomcat时遇到了异常。 任何帮助都很感激。 原因:org.hibernate.engine.JNDI.jndiException:无法在org.hibernate.engine.JNDI.internal.jndiserviceimpl.locate(jndiserviceimpl.java:117)在org.hibernate.engine
我有一个小问题,所以我一直在做这个程序,出于某种原因,它抛出了一个空指针异常。我已经让它工作了,但它不会显示我试图创建的JTable,只是一个空白窗口,当我包含代码时,它就会崩溃。。。。有什么想法吗?
问题内容: 我目前正在使用play2框架。 我有几个正在抛出的类,但是play2s全局处理程序使用throwable而不是异常。 例如我的一门课是抛出一个。我是否可以检查可抛物体(如果是)? 问题答案: 您可以使用它来检查它是否存在。 例: 假设是参考。