首页 > 解决方案 > Spring @Async 失败并拒绝执行异常

问题描述

我们需要并行运行任务,所以我们使用 spring @Async 功能。为了提供执行器配置,我们正在创建一个执行器 bean。

@Bean(name = "async")
    public Executor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(5);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.initialize();
        return executor;
    } 

一旦并行任务的数量超过 maxpoolSize + 队列大小,下一个任务提交就会失败,并出现拒绝执行异常。

为了克服这个问题,我们从源代码中研究了调用方中止策略:https ://www.baeldung.com/java-rejectedexecutionhandler ,它提供了主线程本身在队列和线程已经满的情况下运行任务的工具。

设置需要是:executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

Q1。我需要了解 ThreadPoolTask​​Executor 使用 LinkedBlocking queue ,我的期望是,一旦最大池线程和队列大小已满并被占用,主线程将在提交新任务时被阻塞,但它会因 RejectedException 而失败,即使阻塞队列存在于 ThreadPoolTask​​Executor 中?

Q2。为了克服这个问题,我们如何实现一个阻塞机制,在这个机制中,main 在提交新任务或自行运行时不会失败(如在 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()) 中)但被阻塞以获得可用空间在队列中将任务放入队列中?

标签: multithreadingthreadpoolexecutorspring-async

解决方案


无限期地阻塞主线程会导致死锁情况。这就是为应用程序用户提供处理程序以决定当线程池队列容量超过时应该采取什么行为的原因。

如下线程中所讨论的,可以实现所需阻塞行为的各种实现,但应注意阻塞多长时间和其他死锁场景。

队列满时ThreadPoolExecutor阻塞?


推荐阅读