遇到java.util.concurrent.RejectedExecutionException

目前看来,最主要有2种原因。

第一:

你的线程池ThreadPoolExecutor 显示的shutdown()之后,再向线程池提交任务的时候。 如果你配置的拒绝策略是AbortPolicy的话,这个异常就会抛出来。

第二:

当你设置的任务缓存队列过小的时候,或者说, 你的线程池里面所有的线程都在干活(线程数== maxPoolSize),并且你的任务缓存队列也已经充满了等待的队列, 这个时候,你再向它提交任务,则会抛出这个异常。

下面用例子来说明一下,两种情况:

第一种, 显示关闭掉了线程池

这一点其实理解起来很简单, 比如说,你向一个仓库去存放货物,一开始,仓库管理员把门给你打开了,你放了第一件商品到仓库里面,但是当你放好出去的时候,不小心把仓库的门关掉了, 那么你下次再来存放的时候, 你就会被拒绝掉。

落实到代码就是:

ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(5, 10, 3000L, TimeUnit.MILLISECONDS,  new LinkedBlockingQueue<Runnable>(4));

for (int i = 0; i < 2; i++) {

EXECUTOR.execute(new Runnable() {

public void run() {

System.out.println("Hello World");

}

});

EXECUTOR.shutdown();

}

 
01 ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(5, 10, 3000L, TimeUnit.MILLISECONDS,
02                                                           new LinkedBlockingQueue<Runnable>(4));
03      for (int i = 0; i < 2; i++) {
04          EXECUTOR.execute(new Runnable() {
05              public void run() {
06                  System.out.println("Hello World");
07              }
08          });
09          EXECUTOR.shutdown();
10      }

如上, 在我们提交第一个任务之后,线程池就被关闭掉了。 那么你再向线程池提交新任务的时候,你就会遇到类似的异常。

为什么会这样?

原因是,在ThreadPoolExecutor内部,存放着当前这个线程池的运行状态。

当你调用shutdown的时候, 线程池会有顺序的将线程池中正在运行的任务给关闭掉。InterruptException这样的异常。

第二种代码如下:

for (int i = 0; i < 15; i++) {

final int tmpint=i;

EXECUTOR.execute(new Runnable() {

public void run() {

try {

System.out.println(tmpint+"Hello World");

Thread.sleep(1000);

} catch (InterruptedException e) {

}

}

});

}

 
01 for (int i = 0; i < 15; i++) {
02          final int tmpint=i;
03          EXECUTOR.execute(new Runnable() {
04              public void run() {
05                  try {
06                      System.out.println(tmpint+"Hello World");
07                      Thread.sleep(1000);
08                  } catch (InterruptedException e) {
09                  }
10              }
11          });
12      }

类似的,当你的线程池中 ,正在执行包括正在等待的线程数有 maxPool + workQueueSize 这个数量的话。 再次向它提交任务,则会遇到这个异常。

比如,上面的线程数: 如果当前线程正在跑的数量 <最大线程, 再加上等待的, 都有我们的业务点吗?

解决办法:

针对第一种,可以再往线程池存放线程之前先判断线程池是否已经关闭

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ExecutorServiceDemo {

static class MyThread implements Runnable {

public void run() {

   try {

    Thread.sleep(500);

    // System.out.println("MyThread...");

   } catch (InterruptedException e) {

    e.printStackTrace();

   }

  }

 }

public static void main(String[] args) {

ExecutorService pool = Executors.newFixedThreadPool(20);

  

  System.out.println("pool start ...");

  

  for (int i = 0; i < 1000; i++) {

   

   try {

if(!pool.isShutdown()){

     

     pool.execute(new MyThread());

    }

if (i == 300) {

     

     pool.shutdown();

    }

    

   } catch (Exception e) {

    

    e.printStackTrace();

   }

  }

  System.out.println("pool end ...");

 }

}

第二种:

可以将线程池的数量调大点(minPoolSize,maxPoolSize,handlerList)这新信息。

关于 java.util.concurrent.RejectedExecutionException的更多相关文章

  1. java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejected from java.util.concurrent.ThreadPoolExecutor@11f7cc04[Terminated, pool size = 0, active threads

    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@1f303192 rejec ...

  2. java.util.concurrent.RejectedExecutionException: event executor terminated解决方法之一

    INFO | jvm 1 | 2017/03/09 19:45:10 | java.util.concurrent.RejectedExecutionException: event executor ...

  3. java.util.concurrent.RejectedExecutionException

    java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@59f1ca76 rejec ...

  4. java.util.concurrent.RejectedExecutionException 线程池饱和

    java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPoli ...

  5. newSingleThreadScheduledExecutor连续关闭造成 java.util.concurrent.RejectedExecutionException

    Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util ...

  6. Caused by: java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED! Thread Name:

    异常引发的问题: 线程模型 如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,⽐如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度. 但如果事件处理逻辑较慢,或者需 ...

  7. java.util.concurrent包API学习笔记

    newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...

  8. java.util.concurrent.ThreadPoolExecutor

    java.util.concurrent.ThreadPoolExecutor An ExecutorService that executes each submitted task using o ...

  9. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

  10. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

随机推荐

  1. 【YashanDB知识库】存储过程报错snapshot too old

    问题描述 20231127上午客户反馈绩效系统20231125.20231126出现2次YAS-02020 snapshot too old的问题,测试也有类似问题. 该过程是客户新增的存储过程,目的 ...

  2. 通过DashScope API调用将多种模态转换为向量

    本文介绍如何通过模型服务灵积DashScope进行 多模态向量生成 ,并入库至向量检索服务DashVector中进行向量检索. 模型服务灵积DashScope,通过灵活.易用的模型API服务,让各种模 ...

  3. 计算QPS-Sentinel限流算法

    sentinel 前方参考 计算QPS-Sentinel限流算法 https://www.cnblogs.com/yizhiamumu/p/16819497.html Sentinel 介绍与下载使用 ...

  4. AI构建新质生产力,合合信息Embedding模型助力专业知识应用

    一.合合信息acge模型获MTEB中文榜单第一   现阶段,大语言模型的飞速发展吸引着社会各界的目光,背后支撑大型语言模型应用落地的Embedding模型也成为业内关注的焦点.近期,合合信息发布了文本 ...

  5. 掌握 C++17:结构化绑定与拷贝消除的妙用

    C++17 特性示例 1. 结构化绑定(Structured Binding) 结构化绑定允许你用一个对象的元素或成员同时实例化多个实体. 结构化绑定允许你在声明变量的同时解构一个复合类型的数据结构( ...

  6. 平面设计 – 色轮 & 配色

    前言 由于之前那篇有点长, 而且色轮很重要, 所以独立写一篇呗. 参考: 一文看懂色轮 Youtube – 03 色彩 (什么是色相.纯度.明度.色环.补色?怎样配色?) Youtube – 初學繪畫 ...

  7. Angular 学习笔记 (Typescript 版本更新)

    记入每一期我会用到的功能 : v4.3  1. getter setter 的类型可以不一样咯, 这个困扰很久了.  (interface, object, class 都可以这样用) class T ...

  8. acme+cloudflare生成免费证书(自动续期)

    acme DNSapi acme DNSapi的作用是在申请证书时使用dns交易,acme可以通过dnsapi在对应的dns管理平台提交对应的dns记录.玩过证书的朋友都知道,证书申请时有三种验证方式 ...

  9. Vscode 远程切换Python虚拟环境

    在VSCode中远程切换Python虚拟环境是一个涉及多个步骤的过程,包括安装必要的扩展.连接到远程服务器.创建或激活虚拟环境,并在VSCode中选择相应的Python解释器.以下是一个详细的步骤指南 ...

  10. “全栈合一 智慧运维”智和网管平台SugarNMS V9版本发布

    以"管控万物 无所不能 无处不"在为产品创新理念,智和信通打造"全栈式"网络安全运维平台-智和网管平台SugarNMS.立足数字化.智能化.可视化.自动化,整合 ...