我是靠谱客的博主 瘦瘦凉面,最近开发中收集的这篇文章主要介绍Java并发编程系列30:抛出异常 java.util.concurrent.RejectedExecutionException,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1、背景介绍

Java使用线程池newFixedThreadPool针对算法进行并发测试时,出现以下错误java.util.concurrent.RejectedExecutionException

Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.cipherxxxcrypto.pertest.SM4PerTest$DecTask@76ed5528 rejected from java.util.concurrent.ThreadPoolExecutor@2c7b84de[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 4]
	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)
	at com.cipherxxx.crypto.pertest.SM4PerTest.main(SM4PerTest.java:68)

java.util.concurrent.ThreadPoolExecutor@2c7b84de[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 4]

发现pool size 的值是0,active threads的值是0,

poolSize:线程池中当前线程的数量

active threads:活动线程数

queued tasks:任务队列数

2、分析ThreadPoolExecutor类

ThreadPoolExecutor类,引发java.util.concurrent.RejectedExecutionException主要有两种原因:

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

2)、当你的排队策略为有界队列,并且配置的拒绝策略是ThreadPoolExecutor.AbortPolicy,当线程池的线程数量已经达到了maximumPoolSize的时候,你再向它提交任务,就会抛出ThreadPoolExecutor.AbortPolicy异常。

3、分析本次多线程程序的原因

3.1、本次测试用的线程池是:newFixedThreadPool

1)该线程池未自定义拒绝策略,所以使用的默认拒绝策略,

线程池的默认拒绝策略为ThreadPoolExecutor.AbortPolicy,即直接抛出RejectedExecutionException异常.

直接抛出个RejectedExecutionException异常,也不执行这个任务了

2)线程数量固定的线程池(定长线程池),可控制线程最大并发数,超出的线程会在队列中等待。而队列LinkedBlockingQueue,LinkedBlockingQueue很大,任务不多的情况下,不会因为任务多导致调用到拒绝策略。

3.2、代码的最后结论

加密用的线程池对象和解密用的线程池对象都是同一个,加密时会调用到exs.shutdown();所以导致了线程池已经关闭了,还继续去请求任务。

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

4、解决办法

在加密任务和解密任务中分别创建线程池对象。

原有:

        //创建一个拥有固定线程数的线程池对象

        ExecutorService exs = Executors.newFixedThreadPool(threadCount);

解决后:

   //创建一个拥有固定线程数的线程池对象
        ExecutorService exs;

        String[] type={"sm4_encrypt","sm4_decrypt"};
        for  (String str :type) {
            if (str=="sm4_encrypt") {//加密
                exs = Executors.newFixedThreadPool(threadCount);
                for (int i = 0; i < threadCount; ++i) {
                    //通过 ExecutorService 对象的 execute 方法将任务添加到线程去执行(获取到运行时间)
                    exs.execute(new EncTask(barrier, loopNum, i, sm4, plainData, key, iv));
                }
            }else {//解密
                exs = Executors.newFixedThreadPool(threadCount);
                for (int i = 0; i < threadCount; ++i) {
                    //通过 ExecutorService 对象的 execute 方法将任务添加到线程去执行(获取到运行时间)
                    exs.execute(new DecTask(barrier, loopNum, i, sm4, cipher, key, iv));
                }
            }

            exs.shutdown();
       }

Yet,不再报错,问题解决。

参考:https://blog.csdn.net/fen_fen/article/details/122833164

https://blog.csdn.net/fen_fen/article/details/122909142

https://blog.csdn.net/u010657094/article/details/110477635

https://baijiahao.baidu.com/s?id=1697728751268529678&wfr=spider&for=pc

最后

以上就是瘦瘦凉面为你收集整理的Java并发编程系列30:抛出异常 java.util.concurrent.RejectedExecutionException的全部内容,希望文章能够帮你解决Java并发编程系列30:抛出异常 java.util.concurrent.RejectedExecutionException所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(38)

评论列表共有 0 条评论

立即
投稿
返回
顶部