【Java】SpringBoot实现异步任务(案例实现)

        在Spring Boot中,异步任务是一种机制,允许将某些方法或操作异步执行,以提高应用程序的性能和响应性。通过使用Spring的异步支持,你可以让某个方法在单独的线程中执行,而不必等待其完成,从而避免阻塞主线程。

Spring Boot的异步任务通常使用以下几个核心注解

  1. @EnableAsync:

    • 在Spring Boot应用程序的配置类上添加@EnableAsync注解,以启用异步任务支持。这样Spring会为异步方法创建一个代理,允许它们在单独的线程中执行。
  2. @Async:

    • 在需要异步执行的方法上添加@Async注解。这告诉Spring框架将这个方法的调用包装在一个新的线程中执行。

举个简单的开发场景:

        假如管理员要发布一条消息,需要向数据库添加一条消息,并且将消息通知给所有用户,但是呢通知的用户量超级大,执行起来就比较慢,所以就可以将通知用户的逻辑使用异步的方式进行修改。

SpringBoot异步任务

1 使用注解@EnableAsync开启异步任务支持
@SpringBootApplication
@EnableAsync//开启异步任务支持
public class ApplicationStarter {
  public static void main(String[] args) {
      SpringApplication.run(ApplicationStarter.class,args);
  }
}
2创建一个Spring 的配置类,用于配置异步任务执行器

        注意:如果你部署的服务器本身是单核的,就算创建线程池其实也不会提高执行效率,实际上还是串行的。

@Configuration
public class ExcuterConfig {

    /**
     * 配置异步任务执行器
     * @return 返回一个ThreadPoolExecutor对象,用于异步任务的执行
     */
    @Bean(name = "myTaskExecutor")
    public ThreadPoolExecutor getAsyncExecutor() {
        // 创建一个ThreadPoolExecutor对象,用于执行异步任务
        // 设置核心线程数为3,最大线程数为6,空闲线程60秒后被回收
        // 使用LinkedBlockingDeque作为任务队列,最大容量为10000
        return new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10000));
    }
}
3.添加消息的Controller控制层
@PostMapping("/addMessage")
public ResultInfo<String> addMessage(@RequestBody @Valid Message message) {
    if (message == null) {
        return new ResultInfo<String>().error("请传递message参数");
    }
    try {
        long startTime = System.currentTimeMillis();
        //添加消息到Message数据库
        Integer messageId = messageService.addMessage(message);
        if (messageId!=0) {
            //异步新增数据到UserMessage库中
            messageService.asyncBatchInsertUserMessage(messageId);
            long endTime = System.currentTimeMillis();
            System.out.println("同步执行时间:" + (endTime - startTime) + "毫秒");
            return new ResultInfo<String>().succeed("新增消息成功");
        } else {
            return new ResultInfo<String>().error("新增消息失败");
        }

    } catch (Exception ex) {
        logger.error("服务器异常,请稍后重试!" + ex.getMessage());
        return new ResultInfo<String>().interrupt(ex.getMessage());
    }
}
4.业务层Service

同步添加消息表

@Override
@Transactional
public Integer addMessage(Message message) {
    try {
        message.setNoticeTime(new Date());
        long startTime = System.currentTimeMillis();
        // 直接进行修改
        messageMapper.addMessage(message);
        // 应该对数据库中所有用户进行通知
        // 保存后生成的自增长id
        Integer messageId = message.getId();
        System.out.println("新增消息的message_id:" + messageId);
        return messageId;
    } catch (Exception e) {
        // 添加过程中发生异常,可以进行日志记录等操作
        log.error("Error addMessage message: {}", e.getMessage(), e);
        return 0;
    }
}

异步添加用户信息表

    @Override
    @Async("myTaskExecutor")
    public void asyncBatchInsertUserMessage(Integer messageId) {
        try {
            long startTime = System.currentTimeMillis();
            List<Users> userList = userMapper.findAll();
            
            // 批量插入UserMessage
            if (!userList.isEmpty()) {
                userMessageMapper.batchInsert(userList);
            }
            long endTime = System.currentTimeMillis();
            System.out.println("异步执行时间:" + (endTime - startTime) + "毫秒");
            System.out.println("异步执行");
        } catch (Exception e) {
            // 异常处理
            log.error("异步发布消息给用户失败,对刚才发布的消息进行删除: {}", e.getMessage(), e);
            messageMapper.deleteById(messageId);
        }
    }

这样就使用SpringBoot实现了一个简单的异步功能。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mxin5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值