SpringBoot使用@Async注解,实现异步任务

news2024/9/22 19:34:24

1.直接在方法上加@Async注解,标明为异步任务:

@Component
public class MyAsyncTask {
     @Async
    public void asyncImportTask(String jsonList){
        //...具体业务逻辑
        //从redis缓存中查询数据(使用若依框架自带的redis方法)
        Data redisData = RedisUtils.getCacheObject(DataEnum.NUMONE.getValue());
        if(ObjectUtil.isEmpty(redisData)){
            //将数据查询后存入redis缓存1H
            RedisUtils.setCacheObject(DataEnum.NUMONE.getValue(), Data, Duration.ofHours(1));
        }
    }
}

2.设置默认的Async的线程,且开启异步配置,即配置上@EnableAsync注解:

@EnableAsync(proxyTargetClass = true)
@Configuration
public class AsyncConfig extends AsyncConfigurerSupport {

    @Autowired
    @Qualifier("scheduledExecutorService")
    private ScheduledExecutorService scheduledExecutorService;

    /**
     * 自定义 @Async 注解使用系统线程池
     */
    @Override
    public Executor getAsyncExecutor() {
        return scheduledExecutorService;
    }

    /**
     * 异步执行异常处理
     */
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return (throwable, method, objects) -> {
            throwable.printStackTrace();
            StringBuilder sb = new StringBuilder();
            sb.append("Exception message - ").append(throwable.getMessage())
                .append(", Method name - ").append(method.getName());
            if (ArrayUtil.isNotEmpty(objects)) {
                sb.append(", Parameter value - ").append(Arrays.toString(objects));
            }
            throw new ServiceException(sb.toString());
        };
    }
}

3.使用的线程池相关配置:

//线程池配置
@Configuration
public class ThreadPoolConfig {

    /**
     * 核心线程数 = cpu 核心数 + 1
     */
    private final int core = Runtime.getRuntime().availableProcessors() + 1;

    @Autowired
    private ThreadPoolProperties threadPoolProperties;

    @Bean(name = "threadPoolTaskExecutor")
    @ConditionalOnProperty(prefix = "thread-pool", name = "enabled", havingValue = "true")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(core);
        executor.setMaxPoolSize(core * 2);
        executor.setQueueCapacity(threadPoolProperties.getQueueCapacity());
        executor.setKeepAliveSeconds(threadPoolProperties.getKeepAliveSeconds());
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }

    /**
     * 执行周期性或定时任务
     */
    @Bean(name = "scheduledExecutorService")
    protected ScheduledExecutorService scheduledExecutorService() {
        return new ScheduledThreadPoolExecutor(core,
            new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
            new ThreadPoolExecutor.CallerRunsPolicy()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                Threads.printException(r, t);
            }
        };
    }
}

4.线程池配置属性

//线程池配置属性
@Data
@Component
@ConfigurationProperties(prefix = "thread-pool")
public class ThreadPoolProperties {

    /**
     * 是否开启线程池
     */
    private boolean enabled;

    /**
     * 队列最大长度
     */
    private int queueCapacity;

    /**
     * 线程池维护线程所允许的空闲时间
     */
    private int keepAliveSeconds;

}

5.系统全局线程池配置

# 全局线程池相关配置
thread-pool:
  # 是否开启线程池
  enabled: true
  # 队列最大长度
  queueCapacity: 256
  # 线程池维护线程所允许的空闲时间
  keepAliveSeconds: 300

注意:调用被@Async注解的方法时,调用方法不能与被调用方法放在同一类中,否则注解不生效

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2155751.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【25.6】C++智能交友系统

常见错误总结 const-1 如下代码会报错 原因如下: man是一个const修饰的对象,即man不能修改任何内容,但是man所调用的play函数只是一个普通的函数,所以出现了报错。我们需要在play函数中加上const修饰,或者删除man对…

《论分布式存储系统架构设计》写作框架,软考高级系统架构设计师

论文真题 分布式存储系统(Distributed Storage System)通常将数据分散存储在多台独立的设备上。传统的网络存储系统采用集中的存储服务器存放所有数据,存储服务器成为系统性能的瓶颈,也是可靠性和安全性的焦点,不能满…

FreeRTOS-时间片调度

FreeRTOS-时间片调度 一、时间片调度简介二、时间片调度实验 一、时间片调度简介 同等优先级任务轮流的享有相同的CPU时间(可设置),叫时间片,在FreeRTOS中,一个时间片就等于SysTick中断周期,所以说时间片大小取决于滴答定时器中断…

windows安装Anaconda教程

一、简介 Anaconda 是一个开源的 Python 和 R 语言的分发平台,专为科学计算和数据分析设计。它包含了包管理器 Conda,可以方便地安装和管理库、环境和依赖项。此外,Anaconda 还附带了许多数据科学工具和库,如 Jupyter Notebook 和…

【HTTPS】中间人攻击和证书的验证

中间人攻击 服务器可以创建出一堆公钥和私钥,黑客也可以按照同样的方式,创建一对公钥和私钥,冒充自己是服务器(搅屎棍) 黑客自己也能生成一对公钥和私钥。生成公钥和私钥的算法是开放的,服务器能生产&…

iOS17找不到developer mode

iOS17找不到开发者模式 developer mode 下载过app之后、弹窗Developer Mode Required之后,这个菜单就出现了(之前死活找不到)。 背景:用蒲公英分发测试app,有个同事买了新机(iphone 15 pro max),添加了白名…

双虚拟机部署php项目

前言 经过前面的学习,我们对分布式部署有了一定的了解,这次我们尝试做些东西 准备 我打算用虚拟机部署一个外联网盘 一台虚拟机安装php另一台安装MySQL,但是之前已经安装过 MariaDB 了,就不打算改了。 通常MariaDB与MySQL兼容性很好,可以作为替代使用。彩虹外链网盘项目…

OpenAI的O1模型达到AGI二级,类人推理能力被提示危险,细思极恐!

大家好,我是Shelly,一个专注于输出AI工具和科技前沿内容的AI应用教练,体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具,拥抱AI时代的到来。 今天让我们一起来聊聊最近科技圈的大新闻—…

Java笔试面试题AI答之设计模式(4)

文章目录 16. 简述什么是观察者模式?基本概念主要特点实现方式应用场景优缺点 17. 请列举观察者模式应用场景 ?18. 请用Java代码实现观察者模式的案例 ?19. 什么是装饰模式?定义与特点结构与角色工作原理优点应用场景示例 20. 请用…

队列的各种接口的实现(C)

队列的概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 队列的实…

【GlobalMapper精品教程】088:按点线面空间位置选择案例

按点线面空间位置选择的原则为:点线面的排列组合。 文章目录 一、选择线要素附近的点二、选择相交或触碰所选线的区和线三、选择包含点的区要素四、选择选定区域内的点要素一、选择线要素附近的点 启动该工具之前,首先要选择线,例如,选择某一段铁路5km范围之内的县城驻地。…

nacos适配人大金仓的数据库

前言 在微服务架构中,服务发现和配置管理是关键组件。Nacos作为一个动态服务发现和配置管理平台,支持多种数据库作为其后端存储。本文将探讨如何在Nacos中适配人大金仓数据库,以及在此过程中的最佳实践。 Nacos简介 Nacos(Nami…

安装 depot_tools 和 Windows 10 SDK 为在Windows下构建基于 chromium 的浏览器(103.0.5060.68 之二)

本文已首发于: 秋码记录 为何要安装depot_tools 虽然我们在上一篇 Windows构建基于 Chromium 的浏览器之环境准备篇安装 Visual Studio(103.0.5060.68 之一) ,已经在Windows系统安装好了Visual Studio 2019 Community版本。 然…

第十二周:机器学习

目录 摘要 Abstract 一、非监督学习 二、word embedding 三、transformer 1、应用 2、encoder 3、decoder 四、各类attention 1、最常见的类别 2、其余种类 3、小结 总结 摘要 本周继续学习机器学习的相关课程,首先了解了监督学习和非监督学习的概…

数据结构与算法——Java实现 9.习题——删除链表倒数节点

目录 19. 删除链表的倒数第 N 个结点 方法1 通过链表长度直接删除 方法2 递归加入哨兵节点 ListNode 方法3 快慢指针法 苦难,区区挫折罢了,而我必定站在幸福的塔尖 —— 24.9.22 19. 删除链表的倒数第 N 个结点 给你一个链表,删除链表的倒数第…

【LeetCode】146. LRU缓存

1.题目 2.思想 3.代码 3.1 代码1 下面这是一版错误的代码。错误的原因在于逻辑不正确导致最后的代码也是不正确的。 class LRUCache:def __init__(self, capacity: int):self.time 0 # 用于全局记录访问的时间self.num2time {} # 数字到时间的映射self.key2val {} # 数字…

第十四章:html和css做一个心在跳动,为你而动的表白动画

💖 让心跳加速,传递爱意 💖 在这个特别的时刻,让爱在跳动中绽放!🌟 无论是初次相遇的心动,还是陪伴多年的默契,我们的心总在为彼此跳动。就像这颗炙热的爱心,随着每一次的跳动,传递着满满的温暖与期待。 在这个浪漫的季节,让我们一同感受爱的律动!无论你是在…

Linux文件IO(七)-复制文件描述符

在 Linux 系统中,open 返回得到的文件描述符 fd 可以进行复制,复制成功之后可以得到一个新的文件描述符,使用新的文件描述符和旧的文件描述符都可以对文件进行 IO 操作,复制得到的文件描述符和旧的文件描述符拥有相同的权限&#…

自学笔记之TVM编译器框架 ,核心特性,模型优化概述,AI应用落地

最近在学习一些和芯片 AI相关的知识,重点了解了一下TVM,我自己认为TVM在AI应用落地类似的项目中,用途还是非常广泛的,现在把一些重要的笔记贴在下面,有两篇原帖链接也附上,感兴趣的同学可以学习一下。 TVM…

宝塔linux 安装code-server指定对应的端口无法访问

这个一般就是nginx搞的鬼,如果服务正常启动,就是访问不了;大概就是宝塔安装的nginx配置没有代理code-server服务对应的端口,一般就是nginx配置文件的问题 安装默认的nginx会有一个配置文件 直接拉到最后会有一行这个&#xff0c…