文档章节

java.util.concurrent.RejectedExecutionException

今日竹石
 今日竹石
发布于 2014/03/15 09:52
字数 750
阅读 136
收藏 0

遇到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)这新信息。


© 著作权归作者所有

今日竹石
粉丝 41
博文 227
码字总数 181312
作品 0
朝阳
程序员
私信 提问
JAVA使用timetask管理线程池时出现错误

要定时爬取代理网站上的代理Ip 开了一个线程池用来爬取 用timetask来进行定时 异常信息如下 我是想要在20分钟后重新开一个线程池的 但是不知道为什么上一个线程池shutdown后会抛出下面异常 ...

2016/09/29
196
1
BlockingThreadPoolExecutor

/** Customed ThreadPoolExecutor , when all the core thread are actived and the buffer queue * is full , we cannot submit new task to the threadpool , with Semaphore . */ import ......

Yixin_Nemo
2018/07/10
0
0
Tomcat 的异常:RejectedExecutionException: Work queue full.

Socket processing request was rejected for:org.apache.tomcat.util.net.NioC hannel@730f60e:java.nio.channels.SocketChannel[connected local=/127.0.0.1:9082 r emote=/127.0.0.1:4979......

红薯
2012/11/22
1K
5
rejected from java.util.concurrent.ThreadPoolExe错误

java.util.concurrent.RejectedExecutionException:Task com.dangdang.product.cron.job.JobRun$2@6e9764d4rejected from java.util.concurrent.ThreadPoolExecutor@740642a9[Shutting down,......

macker
2014/01/20
0
0
解决AsyncTask引发的RejectedExecutionException

AsyncTask是google为易用和有效的异步操作UI线程的所开发的一个封装类。使用者可以很轻易的使用其进行后台操作,然后将结果传给UI线程,而不需要使用Thread和Handler。 这样好用的一个类,显...

今日竹石
2014/03/17
0
1

没有更多内容

加载失败,请刷新页面

加载更多

recv send 的 MSG_DONTWAIT 、 MSG_WAITALL 参数

基本概念: 阻塞IO:: socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回。 非阻塞IO:: 非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功。 ...

shzwork
28分钟前
2
0
怎么给开源项目提PR?

1. Fork 你想要提交 PR 的项目 2. 下载到本地 相关步骤如下: 在你需要的文件夹下面,右键使用 git bash 命令,打开 git 命令框 执行如下指令可将项目代码下载到当前目录 1代码仓库地址为示例...

xiaomin0322
32分钟前
2
0
浅复制与深复制概念

1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制...

GodIsCj
32分钟前
1
0
如何在工作中快速成长?致工程师的10个简单技巧

阿里妹导读:阿里有句非常经典的土话,“今天的最好表现,是明天的最低要求。”如何挖掘潜能、发现更好的自己?今天,阿里巴巴高级无线开发专家江建明将认知升级的方法总结出来,帮助你获得快...

阿里云官方博客
54分钟前
2
0
如何 SSH 到 Linux 服务器里的特定目录及执行命令?

这种操作对于新手来讲特别常见,良许之前也是这样。在本文,老司机将带你来进行更高效的操作,只需一步即可达到你想要的效果。 而且,不仅仅是实现快速进入到 Linux 服务器特定的目录,还可以...

架构师springboot
59分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部