为了账号安全,请及时绑定邮箱和手机立即绑定

我无法通过 ExecutorService 获得

我无法通过 ExecutorService 获得

拉莫斯之舞 2021-12-01 15:56:59
我为 RejectedExecutionException 的测试处理创建了调度程序:@Componentpublic class TestScheduler {    private final TestService testService;    private ExecutorService executorService;    public TestScheduler(TestService testService) {        this.testService = testService;    }    @PostConstruct    public void init() {        executorService = Executors.newFixedThreadPool(5);    }    @Scheduled(fixedRate = 10L)    public void test() {        System.out.println("test");        executorService.execute(testService::print);    }}和延迟 70 秒的服务:@Componentpublic class TestService {    public void print() {        System.out.println("print start");        try {            TimeUnit.SECONDS.sleep(70);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("print end");    }}我等待下一个逻辑:调度程序调用executorService.execute(testService::print)5 次每个testService::print将执行 70 秒当execute方法第六次调用我得到RejectedExecutionException但我没有得到异常。我有这个日志:testprint start2018-10-22 11:26:45.543  INFO 5960 --- [           main] c.e.s.SchedullerExceptionsApplication    : Started SchedullerExceptionsApplication in 0.661 seconds (JVM running for 1.108)testprint starttestprint starttestprint starttestprint starttest...70 seconds print test
查看完整描述

2 回答

?
猛跑小猪

TA贡献1858条经验 获得超8个赞

定义执行器时涉及两个方面。

  1. 执行程序将使用的线程数。这限制了执行程序可以运行的并发任务的数量。这是您通过Executors.newFixedThreadPool(5).

  2. 底层任务提交队列的大小。这限制了底层队列可以存储的任务数量,直到它抛出异常。创建的执行器newFixedThreadPool使用无界队列,因此您不会收到异常。

您可以通过如下创建自己的执行程序服务并向其提交 11 个任务(5 个使用所有线程,5 个填充底层任务队列和 1 个溢出它)来实现您想要的行为。

new ThreadPoolExecutor(5, 
                       5, 
                       2000L, 
                       TimeUnit.MILLISECONDS, 
                       new ArrayBlockingQueue<Runnable>(5, true), 
                       new ThreadPoolExecutor.CallerRunsPolicy());


查看完整回答
反对 回复 2021-12-01
?
牛魔王的故事

TA贡献1830条经验 获得超3个赞

RejectedExecutionException将被抛出您溢出任务队列(并且现在是未绑定的),而您希望在安排更多任务时抛出它(将其放入可能是无限制的队列)然后您有工作人员 - 这是废话,因为这是一种目的worker - 构建队列并从中执行。

要测试错误处理,请模拟您的执行程序并在任务提交时抛出异常(最好),或者使用有限的、有界的、非阻塞队列作为您的执行程序的后备队列。

使用模拟是最简单的方法。


查看完整回答
反对 回复 2021-12-01
  • 2 回答
  • 0 关注
  • 141 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信