关于 java.util.concurrent.RejectedExecutionException
遇到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的更多相关文章
- 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 ...
- java.util.concurrent.RejectedExecutionException: event executor terminated解决方法之一
INFO | jvm 1 | 2017/03/09 19:45:10 | java.util.concurrent.RejectedExecutionException: event executor ...
- java.util.concurrent.RejectedExecutionException
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask@59f1ca76 rejec ...
- java.util.concurrent.RejectedExecutionException 线程池饱和
java.util.concurrent.RejectedExecutionException at java.util.concurrent.ThreadPoolExecutor$AbortPoli ...
- newSingleThreadScheduledExecutor连续关闭造成 java.util.concurrent.RejectedExecutionException
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util ...
- Caused by: java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED! Thread Name:
异常引发的问题: 线程模型 如果事件处理的逻辑能迅速完成,并且不会发起新的 IO 请求,⽐如只是在内存中记个标识,则直接在 IO 线程上处理更快,因为减少了线程池调度. 但如果事件处理逻辑较慢,或者需 ...
- java.util.concurrent包API学习笔记
newFixedThreadPool 创建一个固定大小的线程池. shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭. awaitTermination():用于等待子线程结束, ...
- java.util.concurrent.ThreadPoolExecutor
java.util.concurrent.ThreadPoolExecutor An ExecutorService that executes each submitted task using o ...
- 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分
这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...
- 原子类java.util.concurrent.atomic.*原理分析
原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...
随机推荐
- .net core 依赖注入,运行报错 Cannot consume scoped 'xxx' service from singleton 'yyy'
这是因为 xxx 的生命周期是 AddScoped 注入的,而 yyy 的生命周期是 AddSingleton ,然后 yyy 这个单例的对象中,它又依赖了xxx 也就是说,单例注入的对象中依赖了 A ...
- MySQL linux下安装,配置,免密登录与基本认识
目录 MySQL卸载 环境 查看是否已安装MySQL 卸载mysql服务 查看是否卸载干净 MySQL安装 查看linux版本 选择MySQL版本 获取mysql官方yum源 rpm安装mysql官方 ...
- Scala编程语言基本常识
本文参考来源: Scala编程语言基本常识 – 萌面人博客 一 基本常识 Scala被称为大数据的黄金语言,它的发明人是马丁奥德斯基(Martin Odersky) 2001年诞生,融合了Ja ...
- linux操作系统和文件系统,命令(上)
Linux是一个类似于windows的操作系统 Linux操作系统的一种主要使用方式是通过终端软件:终端软件里只能使用键盘不能使用鼠标,在终端软件里通过输入命令完成各种任务 clear命令可以删除终端 ...
- Springboot 项目配置 HTTPS
生成证书 输入命令 keytool -genkeypair -alias "boot" -keyalg "RSA" -keystore "boot.k ...
- Hive----基本概念
Hive 基本概念 1. Hive:由 Facebook 开源用于解决海量结构化日志的数据统计. 2. Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 ...
- 1. 说一下 vue 的父子传参 ?
主要实现的方式: 1. 第一种方法 ,在子组件标签使用自定义属性="参数"和自定义事件,在子组件内使用 props 接受自定义属性 :如果子组件要修改参数,不能直接修改,因为 vu ...
- 我们在 vue 项目中如何做路由导航守卫
一般在 src 文件夹新建一个 permission 文件 ,单独用来做路由导航守卫业务 ,在 main.js 导入文件即可 : 主要功能有 判断是否有 token ,以此判断用户是不是登录了 :
- 静态库封装之ComStr类
ComStr.h #pragma once #include <string> #include <vector> using namespace std; class Com ...
- 最详细CentOS7.6安装openGauss5.0.3教程
一.环境准备 1.1 主机信息 项目 内容 操作系统 CentOS7.6 IP 192.168.4.201 主机名 opgs201 CPU 8core 内存 16GB 磁盘1 100GB 1.2 操作 ...