解决:java.util.concurrent.RejectedExecutionException

 一 发现RejectedExecutionException错误     

      今天查看服务器的时候发现了一些java.util.concurrent.RejectedExecutionException错误,这个是由于线程池里的线程忙不过来报出的。如下图:

像这种 RejectedExecutionException 错误,表明在Java应用程序中,一个任务尝试提交到线程池(ThreadPoolExecutor)去执行时被拒绝了,具体原因是线程池达到了其配置的容量限制,无法接纳更多的任务。下面是错误信息的详细解析:

  从上图可以看到以下线程池信息:

  • Running - 线程池当前处于运行状态。
  • pool size = 100 - 线程池配置的最大线程数为100,意味着它可以同时运行最多100个线程来处理任务。
  • active threads = 100 - 当前有100个线程正在活跃地执行任务,即所有的工作线程都在使用中。
  • queued tasks = 1000 - 任务队列的大小为1000,这意味着当所有线程都在使用时,额外的任务可以排队等待执行,但显然这个队列也已经满了。
  • completed tasks = 253 - 已经有253个任务在这个线程池中完成了执行。

查看报错时间点的cpu运行状态:

从cpu反映来看突然上升而且持续很短,这是由于更新了队列服务器信息一下全部涌过来,很多状态信息是重复的而且变化时间一般十几分钟,大多数信息基本是同样的状态可以忽略不处理,所以这个错误在这种业务环境下是不影响业务,也可以忽略不调整的。但也可以通过调整以下线程池参数优化掉这个错误。

三 解决错误(线程池参数调整)

1. 增加线程池的核心线程数或最大线程数
  • 核心线程数 (corePoolSize): 这些线程即使在空闲时也不会被销毁,增加核心线程数可以让更多的任务直接开始执行而不是等待。
  • 最大线程数 (maximumPoolSize): 设置更高的最大线程数可以容纳更多的并发任务,但也要注意不要设置得太高,以免耗尽系统资源。
2. 调整任务队列的容量
  • 如果你的应用能够容忍一定的延时,增大任务队列的大小可以让更多的任务排队等待执行,而不是直接被拒绝。但这也可能会增加任务的响应时间。
3. 更改拒绝策略
  • Java的ThreadPoolExecutor允许你自定义任务拒绝时的行为。默认情况下,当队列已满且线程数达到最大时,会使用AbortPolicy策略,直接抛出RejectedExecutionException。你可以改为:
    • CallerRunsPolicy: 让调用者所在的线程直接执行任务,这可能会影响主线程的性能。
    • DiscardPolicy: 直接丢弃任务,不执行也不抛出异常。适用于可丢弃的任务。
    • DiscardOldestPolicy: 丢弃队列中最旧的任务,然后尝试重新提交被拒绝的任务。适用于任务执行顺序不敏感的情况。
    • 自定义策略:根据应用需求实现自己的RejectedExecutionHandler

猜你喜欢

转载自blog.csdn.net/qyhua/article/details/139242416