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);
    }
}
相关文章
|
13天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
26天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
13天前
|
Java Spring
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
本文介绍了Spring Boot中静态资源的访问位置、如何进行静态资源访问测试、自定义静态资源路径和静态资源请求映射,以及如何处理自定义静态资源映射对index页面访问的影响。提供了两种解决方案:取消自定义静态资源映射或编写Controller来截获index.html的请求并重定向。
springboot静态资源目录访问,及自定义静态资源路径,index页面的访问
|
6天前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
21 2
|
15天前
|
Java
直接拿来用:进程&进程池&线程&线程池
直接拿来用:进程&进程池&线程&线程池
|
11天前
|
Java
COMATE插件实现使用线程池高级并发模型简化多线程编程
本文介绍了COMATE插件的使用,该插件通过线程池实现高级并发模型,简化了多线程编程的过程,并提供了生成结果和代码参考。
|
1月前
|
监控 Java
线程池中线程异常后:销毁还是复用?技术深度剖析
在并发编程中,线程池作为一种高效利用系统资源的工具,被广泛用于处理大量并发任务。然而,当线程池中的线程在执行任务时遇到异常,如何妥善处理这些异常线程成为了一个值得深入探讨的话题。本文将围绕“线程池中线程异常后:销毁还是复用?”这一主题,分享一些实践经验和理论思考。
60 3
|
2月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
62 0
|
前端开发 Java
Springboot Async异步扩展使用 结合 CompletableFuture
Springboot Async异步扩展使用 结合 CompletableFuture
1088 0
Springboot Async异步扩展使用 结合 CompletableFuture
|
16天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的服装商城管理系统
基于Java+Springboot+Vue开发的服装商城管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的服装商城管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
45 2
基于Java+Springboot+Vue开发的服装商城管理系统