SpringBoot中自定义线程池(@Async使用自定义线程池)

简介: SpringBoot中自定义线程池(@Async使用自定义线程池)

前言

以前负责的一个项目,从单体架构往微服务架构迁移时,引入了Consul作为服务配置中心,然后导致所有的异步定时任务(@schedule+@Async)都不执行了;跟源码发现Consul作为服务配置中心时会在client端起一个定时任务线程池(核心线程数和最大线程数均为1)其伦村Consul Server中的服务配置;

由于@Async默认使用SpringBoot自带的线程池,而这个线程池已经被Consul创建,并且核心线程数和最大线程数都为1,就导致@Async一直拿不到可用的线程,进而所有的定时任务都没有执行;

当时的解决方案:

  • 自定义线程池,@Async使用时指定线程池名称,执行异步任务。

自定义线程池

在@Configuration类中通过@Bean的方式注入一个ThreadPoolTaskExecutor到Spring容器;

@Bean("myExecutor")
public ThreadPoolTaskExecutor mqInvokeAysncExecutor() {

    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    // 线程池中的线程名前缀
    executor.setThreadNamePrefix("log-message-");
    // 设置线程池关闭的时候需要等待所有任务都完成 才能销毁其他的Bean
    executor.setWaitForTasksToCompleteOnShutdown(true);
    // 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
    executor.setAwaitTerminationSeconds(120);
    executor.setCorePoolSize(4);
    executor.setMaxPoolSize(16);
    // 任务阻塞队列的大小
    executor.setQueueCapacity(20000);
    return executor;
}

使用自定义线程池

1)@Async中使用

在使用的方法上面添加@Async(“自定义线程池类beanName”)注解;

public class AsyncTest {

    // 指定使用哪个线程池,不指定则使用spring默认的线程池
    @Async("myExecutor")
    public void executeAsync() {
        System.out.println("executeAsync");
    }
}

2)CompletableFuture中使用

当使用CompletableFuture.runAsync()方法异步执行一系列任务时,可以在方法的第二个参数中指定用哪个线程池执行任务;

public class ImportOrderLogMsgProducer {

    @Resource(name = "myExecutor")
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;



    public void testAsync(LogMessage logMessage) {

        CompletableFuture.runAsync(() -> {

            try {
                // do something
            } catch (Exception e) {
                log.error("... catch:{}", e.getMessage(), e);
            }

        }, threadPoolTaskExecutor);
    }
}
相关文章
|
1天前
|
XML Java 数据格式
Springboot中自定义组件
Springboot中自定义组件
|
1天前
|
Java 调度 Spring
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
SpringBoot实现多线程定时任务动态定时任务配置文件配置定时任务
287 0
|
1天前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
1天前
|
监控 Java Spring
Spring Boot中一般如何使用线程池?
在Spring Boot应用程序中,合理地使用线程池可以有效地提高系统的性能和并发处理能力。本文将深入探讨Spring Boot中如何一般性地使用线程池,包括线程池的配置、使用方式以及一些最佳实践。
24 0
|
1天前
|
前端开发 Java
SpringBoot之自定义注解参数校验
SpringBoot之自定义注解参数校验
19 2
|
1天前
|
Java C++ Spring
谈谈springboot里面的守护线程与本地线程
【4月更文挑战第18天】在Spring Boot中,线程的概念同Java标准线程模型一致,即区分为守护线程和用户线程。Spring Boot本身并不直接提供创建守护线程或用户线程的特殊机制,但它允许你通过标准Java方式或者利用Spring的框架特性来管理这些线程
45 2
|
1天前
|
Java Spring
Springboot如何使用线程池
Springboot如何使用线程池
|
1天前
|
NoSQL Java Redis
Java自定义线程池的使用
Java自定义线程池的使用
|
1天前
|
Java Spring
springboot单类集中定义线程池
该内容是关于Spring中异步任务的配置和使用步骤。首先,在启动类添加`@EnableAsync`注解开启异步支持。然后,自定义线程池类`EventThreadPool`,设置核心和最大线程数、存活时间等参数。接着,将线程池bean注入到Spring中,如`@Bean("RewardThreadPool")`。最后,在需要异步执行的方法上使用`@Async`注解,例如在一个定时任务类中,使用`@Scheduled(cron = "...")`和`@Async`结合实现异步定时任务。
19 2
|
1天前
|
Java 应用服务中间件
Springboot启动的时候初始化的线程池默认配置tomcat
Springboot启动的时候初始化的线程池默认配置tomcat
22 1