当前位置: 首页 > article >正文

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

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.kler.cn/news/318189.html

相关文章:

  • 002.k8s(Kubernetes)一小时快速入门(先看docker30分钟)
  • WPF经典面试题全集
  • JavaEE: 深入探索TCP网络编程的奇妙世界(一)
  • 【MySQL】数据类型【mysql当中各自经典的数据类型的学习和使用】
  • Leetcode 136 只出现一次的数字
  • EfficientFormer实战:使用EfficientFormerV2实现图像分类任务(一)
  • WPF 的TreeView的TreeViewItem下动态生成TreeViewItem
  • 合宙LuatOS应用,与时间相关那些事
  • k8s中pod的创建过程和阶段状态
  • Allegro视频去除走线的小方块
  • Milvus - 四种一致性级别与应用场景解析
  • 可靠传输是什么?是基于UDP实现的吗
  • JUC并发编程_四大函数式接口和 Stream 流式计算
  • 适用于 Windows 的 7 大数据恢复工具,可靠的数据恢复工具可有效地恢复丢失的文件
  • 后端开发工程师转行大模型领域:全面学习路线指南,非常详细收藏我这一篇就够了
  • 【大语言模型_1】VLLM部署Qwen模型
  • 【速成Redis】04 Redis 概念扫盲:事务、持久化、主从复制、哨兵模式
  • 2-102基于matlab的蒙特卡洛仿真
  • C语言——文件操作
  • [数据结构]动态顺序表的实现与应用
  • 第二证券:“产业+科技” 中国并购重组市场持续升温
  • 【微服务即时通讯系统】——etcd一致性键值存储系统,etcd的介绍,etcd的安装,etcd使用和功能测试
  • Scikit-learn 识别手写数字
  • Qt:NULL与nullptr的区别(手写nullptr)
  • 数据处理与统计分析篇-day10-Matplotlib数据可视化
  • Leetcode 每日一题:Diameter of Binary Tree
  • DataWhale X 南瓜书学习笔记 task03笔记
  • vue3+Element-plus el-input 输入框组件二次封装(支持金额、整数、电话、小数、身份证、小数点位数控制,金额显示中文提示等功能)
  • rust属性宏
  • HTML段落,换行,水平线标签与其属性