JAVA 多线程报错 java.util.concurrent.RejectedExecutionException

Posted smile-yan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA 多线程报错 java.util.concurrent.RejectedExecutionException相关的知识,希望对你有一定的参考价值。

问题描述

多线程执行任务的时候,发现报错:

ava.util.concurrent.RejectedExecutionException: Task xxx rejected from java.util.concurrent.ThreadPoolExecutor@5197848c[Running, pool size = 50, active threads = 50, queued tasks = 5, completed tasks = 0]
	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)
	...

Java 代码

创建线程池:

        ExecutorService threadPool = new ThreadPoolExecutor(
                20,
                50,
                1L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(40),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

使用方法:

 for (File file: files) 
            try 
                threadPool.execute(new TaskRunner(data));
             catch (Exception e) 
                System.out.println("[error] " + file.getName());
                e.printStackTrace();
            
        
        threadPool.shutdown();

其中 TaskRunner 是自己定义的实现了 Runnable 的类。

for 循环的时候,总共 files 有 600 个。

问题分析

根据上面的代码,我定义的线程池中等待队列 LinkedBlockingQueue 的长度为 40 。而 for 循环却执行了 600 次,所以队列太短。直接导致这个问题。

解决方法

方法有两个:

  • 事先设置好 LinkedBlockingQueue 的长度,比如 files.length;
  • 不填写 LinkedBlockingQueue 的参数,也就是说,有多少数据就排队多少数据。

如果能事先预估最大长度,建议指定 LinkedBlockingQueue 的长度更加合理。

总结

开发过程中总是会遇到各种各样,奇奇怪怪的问题。

但是这本身就是开发的意义吧。

Smileyan
2022.12.30 12:39

以上是关于JAVA 多线程报错 java.util.concurrent.RejectedExecutionException的主要内容,如果未能解决你的问题,请参考以下文章

21Java并发性和多线程-Java中的锁

java并发之锁的使用浅析

集合类不安全_List_Set_HashMap

JAVA 多线程报错 java.util.concurrent.RejectedExecutionException

JAVA 多线程报错 java.util.concurrent.RejectedExecutionException

Java网络多线程编程——对象流错误导致Connection reset