当前位置:   article > 正文

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

springboot异步执行任务

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

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

  1. @EnableAsync:

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

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

举个简单的开发场景:

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

SpringBoot异步任务

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

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

  1. @Configuration
  2. public class ExcuterConfig {
  3. /**
  4. * 配置异步任务执行器
  5. * @return 返回一个ThreadPoolExecutor对象,用于异步任务的执行
  6. */
  7. @Bean(name = "myTaskExecutor")
  8. public ThreadPoolExecutor getAsyncExecutor() {
  9. // 创建一个ThreadPoolExecutor对象,用于执行异步任务
  10. // 设置核心线程数为3,最大线程数为6,空闲线程60秒后被回收
  11. // 使用LinkedBlockingDeque作为任务队列,最大容量为10000
  12. return new ThreadPoolExecutor(3, 6, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10000));
  13. }
  14. }
3.添加消息的Controller控制层
  1. @PostMapping("/addMessage")
  2. public ResultInfo<String> addMessage(@RequestBody @Valid Message message) {
  3. if (message == null) {
  4. return new ResultInfo<String>().error("请传递message参数");
  5. }
  6. try {
  7. long startTime = System.currentTimeMillis();
  8. //添加消息到Message数据库
  9. Integer messageId = messageService.addMessage(message);
  10. if (messageId!=0) {
  11. //异步新增数据到UserMessage库中
  12. messageService.asyncBatchInsertUserMessage(messageId);
  13. long endTime = System.currentTimeMillis();
  14. System.out.println("同步执行时间:" + (endTime - startTime) + "毫秒");
  15. return new ResultInfo<String>().succeed("新增消息成功");
  16. } else {
  17. return new ResultInfo<String>().error("新增消息失败");
  18. }
  19. } catch (Exception ex) {
  20. logger.error("服务器异常,请稍后重试!" + ex.getMessage());
  21. return new ResultInfo<String>().interrupt(ex.getMessage());
  22. }
  23. }
4.业务层Service

同步添加消息表

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

异步添加用户信息表

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/954294
推荐阅读
相关标签
  

闽ICP备14008679号