multithreading - 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。我需要了解 ThreadPoolTaskExecutor 使用 LinkedBlocking queue ,我的期望是,一旦最大池线程和队列大小已满并被占用,主线程将在提交新任务时被阻塞,但它会因 RejectedException 而失败,即使阻塞队列存在于 ThreadPoolTaskExecutor 中?
Q2。为了克服这个问题,我们如何实现一个阻塞机制,在这个机制中,main 在提交新任务或自行运行时不会失败(如在 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()) 中)但被阻塞以获得可用空间在队列中将任务放入队列中?
解决方案
无限期地阻塞主线程会导致死锁情况。这就是为应用程序用户提供处理程序以决定当线程池队列容量超过时应该采取什么行为的原因。
如下线程中所讨论的,可以实现所需阻塞行为的各种实现,但应注意阻塞多长时间和其他死锁场景。
推荐阅读
- python - 如何使用flask/jinja将值从python传递到html表单
- java - 如何正确接收来自队列 IBM MQ 的消息
- apache-kafka - 当我通过键对数据进行分区,然后在 Kafka 的主题中添加一个新分区时会发生什么?
- elasticsearch - 在 Logstash 配置文件中配置多个数据源?
- embedded-linux - 从正在运行的 linux 系统替换 sama5d3 上的引导加载程序
- php - 发送具有相同名称的多个输入值后未创建数组
- java - Jackson ObjectMapper 将字符串中的名称值序列化为 JSON
- angular - ionViewDidEnter 未在页面刷新时调用
- python - 从以下网站的链接中提取html链接
- authentication - ActiveAdmin::Devise::SessionsController#create 中的 ActionController::InvalidAuthenticityToken