热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

springboot异步(Async)任务调度实现方法

在没有使用springboot之前,我们的做法是在配置文件中定义一个任务池,然后将@Async注解的任务丢到任务池中去执行,那么在springboot中,怎么来实现异步任务的调用了,下面通过本文给大家讲解,需要的朋友参考下

     在没有使用spring boot之前,我们的做法是在配置文件中定义一个任务池,然后将@Async注解的任务丢到任务池中去执行,那么在spring boot中,怎么来实现异步任务的调用了,方法更简单。

我们还是结合前面

spring boot整合JMS(ActiveMQ实现)

这篇博客里面的代码来实现。

一、功能说明

消费者在监听到队列里面的消息时,将接收消息的任务作为异步任务处理。

二、代码修改

消费者1:

package com.chhliu.springboot.jms; 
import org.springframework.jms.annotation.JmsListener; 
import org.springframework.scheduling.annotation.Async; 
import org.springframework.stereotype.Component; 
@Component 
public class Consumer { 
 @JmsListener(destination = "mytest.queue") 
 @Async //该方法会异步执行,也就是说主线程会直接跳过该方法,而是使用线程池中的线程来执行该方法 
 public void receiveQueue(String text) { 
  System.out.println(Thread.currentThread().getName()+":Consumer收到的报文为:"+text); 
 } 
} 

消费者2:

package com.chhliu.springboot.jms; 
import org.springframework.jms.annotation.JmsListener; 
import org.springframework.messaging.handler.annotation.SendTo; 
import org.springframework.stereotype.Component; 
@Component 
public class Consumer2 { 
 @JmsListener(destination = "mytest.queue") 
 @SendTo("out.queue") 
 public String receiveQueue(String text) { 
  System.out.println(Thread.currentThread().getName()+":Consumer2收到的报文为:"+text); 
  return "return message"+text; 
 } 
} 

在测试类上添加如下注解:

package com.chhliu.springboot.jms; 
import javax.jms.Destination; 
import org.apache.activemq.command.ActiveMQQueue; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.test.context.SpringBootTest; 
import org.springframework.scheduling.annotation.EnableAsync; 
import org.springframework.test.context.junit4.SpringRunner; 
@RunWith(SpringRunner.class) 
@SpringBootTest 
@EnableAsync // 开启异步任务支持 
public class SpringbootJmsApplicationTests { 
 @Autowired 
 private Producer producer; 
 @Test 
 public void contextLoads() throws InterruptedException { 
  Destination destination = new ActiveMQQueue("mytest.queue"); 
  for(int i=0; i<100; i++){ 
   producer.sendMessage(destination, "myname is chhliu!!!"); 
  } 
 } 
} 

三、测试结果 

DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-45:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-46:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-47:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-48:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-49:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 
从out.queue队列收到的回复报文为:return messagemyname is chhliu!!! 
SimpleAsyncTaskExecutor-50:Consumer收到的报文为:myname is chhliu!!! 
DefaultMessageListenerContainer-1:Consumer2收到的报文为:myname is chhliu!!! 

从上面的测试结果可以看出,由于消费者2没有使用异步任务方式,所以消费者2消费消息都是由固定的线程DefaultMessageListenerContainer-1这个线程来处理的,而消费者1由于使用了异步任务的方式,每次处理接收到的消息都是由不同的线程来处理的,当接收到消息时,直接将任务丢到任务池中去处理,而主线程则继续跑,从测试结果中还可以推断出,spring boot默认使用了newCachedThreadPool线程池来实现。

关于线程池的具体用法,请参考我的另一篇博文:https://www.jb51.net/article/134870.htm

四、异步任务有返回

在实际的开发中,我们会经常遇到异步任务有返回的情况,那么在spring boot中,怎么来实现了?

下面以异步发邮件为例,来进行说明,示例代码如下:

@Async("taskExecutePool") // 异步任务会提交到taskExecutePool任务池中执行 
 public Future doSendEmail(MailInfo mailInfo) {// 异步任务返回,使用Future来异步返回 
  log.info(Thread.currentThread().getName()+"调用了doSendEmail异步方法!"); 
  SendMailSession session = null; 
  Response res = new Response(); 
  boolean isOK = sendEmail(mailInfo);// 具体发邮件的方法 
 if(isOK){   
  res.setSuccess(true);  
 }else{ 
  res.setSuccess(false); 
 } 
 return new AsyncResult(res); 

返回之后怎么使用?示例代码如下:

Future result = taskJob.doSendEmail(mailInfo); 
   res = result.get(6, TimeUnit.SECONDS); 

这样就可以获取到异步任务的返回了!

总结

以上所述是小编给大家介绍的spring boot异步(Async)任务调度实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


推荐阅读
  • 本文详细分析了一个生产系统中遇到的 Apache Axis2 403 Forbidden 错误,并提供了具体的排查步骤和解决方案。 ... [详细]
  • 本文介绍如何使用 Google 开发的 libphonenumber 库在 Java 应用中实现电话号码的有效性验证。该库不仅支持多种国际电话号码的格式化与解析,还提供了一系列强大的验证工具。 ... [详细]
  • Git SSH配置及远程仓库操作指南
    本文介绍了如何配置Git环境,包括设置用户信息、生成和添加SSH密钥,并详细说明了如何通过SSH连接到远程仓库进行版本控制操作。 ... [详细]
  • 本文详细介绍了如何通过 `vue.config.js` 文件配置 Vue CLI 的打包和代理设置,包括开发服务器配置、跨域处理以及生产环境下的代码压缩和资源压缩。 ... [详细]
  • 本文由Jogis撰写,详细探讨了React中的组件设计模式,包括控制组件、非控制组件及混合模型组件,分析了各自的优缺点及其应用场景。 ... [详细]
  • 本文详细介绍了C++标准模板库(STL)中各容器的功能特性,并深入探讨了不同容器操作函数的异常安全性。 ... [详细]
  • 处理Cookie中包含特殊字符的问题
    探讨了在Web开发中,当Cookie的值中包含特殊字符时,如何正确处理这些值,特别是当值被双引号包围的情况。 ... [详细]
  • 本文通过一个简单的 Python while 循环实例,详细介绍了如何使用 while 循环来控制程序的执行流程。 ... [详细]
  • Flutter入门指南:实现自动关闭的对话框与提示
    本文为Flutter系列教程的一部分,专注于讲解如何在Flutter应用中实现自动关闭的对话框和提示。通过具体的代码示例,帮助开发者掌握SnackBar、BottomSheet和Dialog的使用方法。 ... [详细]
  • 使用Python轻松合并大量复杂Excel文件
    当面对大量的Excel文件时,如何高效地将它们合并成一个文件成为了一项挑战。本文将指导初学者如何利用Python的几个库,在几十行代码内完成这一任务。 ... [详细]
  • Xcode 快捷键与实用技巧
    在iOS开发过程中,熟练掌握Xcode的快捷键可以显著提升工作效率,减少不必要的鼠标操作,让开发者更加专注于代码编写。本文将介绍一些常用的Xcode快捷键及技巧,帮助开发者提高开发效率。 ... [详细]
  • 本文详细探讨了当前主流的两种系统架构——C/S(客户端/服务器)与B/S(浏览器/服务器)架构的特点、优缺点及未来的发展趋势。 ... [详细]
  • 探索Arjun v1.3:高效挖掘HTTP参数的利器
    本文将详细介绍一款名为Arjun的开源安全工具,该工具能够帮助安全研究人员有效提取和分析HTTP参数。请注意,Arjun v1.3要求运行环境为Python 3.4及以上版本。 ... [详细]
  • 手把手教你构建简易JSON解析器
    本文将带你深入了解JSON解析器的构建过程,通过实践掌握JSON解析的基本原理。适合所有对数据解析感兴趣的开发者。 ... [详细]
  • 解决CSS因MIME类型不匹配导致的加载失败问题
    本文详细介绍了在Web开发过程中,遇到CSS文件因MIME类型不匹配而无法正确加载的问题及其解决方案,适合前端开发者阅读。 ... [详细]
author-avatar
爵士独舞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有