一、什么是异步调用
“异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行;异步调用指程序在顺序执行时,不等待异步调用的语句返回结果就执行后面的程序。了解springcloud架构可以加求求:三五三六二四七二五九
二、同步调用
下面通过一个简单示例来直观的理解什么是同步调用:
定义Task类,创建三个处理函数分别模拟三个执行任务的操作,操作消耗时间随机取(10秒内)
@Component public class Task { public static Random random =new Random(); public void doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); } public void doTaskTwo() throws Exception { System.out.println("开始做任务二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务二,耗时:" + (end - start) + "毫秒"); } public void doTaskThree() throws Exception { System.out.println("开始做任务三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务三,耗时:" + (end - start) + "毫秒"); } }
在单元测试用例中,注入Task对象,并在测试用例中执行doTaskOne
、doTaskTwo
、doTaskThree
三个函数。
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class ApplicationTests { @Autowired private Task task; @Test public void test() throws Exception { task.doTaskOne(); task.doTaskTwo(); task.doTaskThree(); } }
执行单元测试,可以看到类似如下输出:
开始做任务一
完成任务一,耗时:4256毫秒
开始做任务二
完成任务二,耗时:4957毫秒
开始做任务三
完成任务三,耗时:7173毫秒
任务一、任务二、任务三顺序的执行完了,换言之doTaskOne
、doTaskTwo
、doTaskThree
三个函数顺序的执行完成。
三、异步调用
上述的同步调用虽然顺利的执行完了三个任务,但是可以看到执行时间比较长,若这三个任务本身之间不存在依赖关系,可以并发执行的话,同步调用在执行效率方面就比较差,可以
考虑通过异步调用的方式来并发执行。
在Spring Boot中,我们只需要通过使用@Async
注解就能简单的将原来的同步函数变为异步函数,Task类改在为如下模式:
@Component public class Task { @Async public void doTaskOne() throws Exception { // 同上内容,省略 } @Async public void doTaskTwo() throws Exception { // 同上内容,省略 } @Async public void doTaskThree() throws Exception { // 同上内容,省略 } }
为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsync,如下所示:
@SpringBootApplication @EnableAsync public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
此时可以反复执行单元测试,您可能会遇到各种不同的结果,比如:
(1)没有任何任务相关的输出
(2)有部分任务相关的输出
(3)乱序的任务相关的输出
原因是目前doTaskOne
、doTaskTwo
、doTaskThree
三个函数的时候已经是异步执行了。主程序在异步调用之后,主程序并不会理会这三个函数是否执行完成了,由于
没有其他需要执行的内容,所以程序就自动结束了,导致了不完整或是没有输出任务相关内容的情况。
注: @Async所修饰的函数不要定义为static类型,这样异步调用不会生效
四、异步回调
为了让doTaskOne
、doTaskTwo
、doTaskThree
能正常结束,假设我们需要统计一下三个任务并发执行共耗时多少,这就需要等到上述三个函数都完成调动之后记录时间,
并计算结果。
那么我们如何判断上述三个异步调用是否已经执行完成呢?我们需要使用Future<T>
来返回异步调用的结果,就像如下方式改造doTaskOne
函数:
@Async public Future<String> doTaskOne() throws Exception { System.out.println("开始做任务一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任务一,耗时:" + (end - start) + "毫秒"); return new AsyncResult<>("任务一完成"); }
按照如上方式改造一下其他两个异步函数之后,下面我们改造一下测试用例,让测试在等待完成三个异步调用之后来做一些其他事情。
@Test public void test() throws Exception { long start = System.currentTimeMillis(); Future<String> task1 = task.doTaskOne(); Future<String> task2 = task.doTaskTwo(); Future<String> task3 = task.doTaskThree(); while(true) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三个任务都调用完成,退出循环等待 break; } Thread.sleep(1000); } long end = System.currentTimeMillis(); System.out.println("任务全部完成,总耗时:" + (end - start) + "毫秒"); }
转载自:http://blog.didispace.com/springbootasync/
相关推荐
在Spring Boot中,可以使用@Async注解来实现异步调用。 使用@Async实现异步调用 在Spring Boot中,使用@Async注解可以将方法异步执行。@Async注解可以应用于方法上,使得该方法可以异步执行。例如: ```java @...
在Spring Boot中,异步调用是通过Spring的`@Async`注解来实现的,它允许我们在不阻塞主线程的情况下执行耗时的操作。这极大地提高了应用的响应速度,尤其是在处理大量并发请求时。接下来,我们将深入探讨如何在...
下面将详细解释如何在Spring Boot中使用`@Async`实现异步调用,以及其背后的原理。 首先,要启用`@Async`注解的功能,需要在Spring Boot的主配置类上添加`@EnableAsync`注解。这会告诉Spring框架,你需要异步任务的...
Spring Boot 异步调用 @Async 过程详解是 Spring Boot 框架中的一种异步调用机制,通过使用 @Async 注解可以将方法异步执行,提高系统的并发性和响应速度。本文将详细介绍 Spring Boot 异步调用 @Async 过程详解的...
在Spring Boot应用中,`@Async`注解用于实现异步方法执行,这极大地提高了应用程序的并发性能。本文将深入探讨`@Async`的工作原理、使用场景以及如何配置和测试。 1. **异步注解的启用** 使用`@EnableAsync`注解在...
在Spring Boot框架中,@Async注解是实现异步任务处理的关键工具,它允许开发者将耗时的操作从主线程中分离出来,以提高应用程序的响应速度。本文将深入探讨@Async的工作原理、配置方法以及使用场景,帮助你更好地...
在Spring Boot应用中,我们可以利用`@Async`注解实现异步调用,这有助于提高应用程序的并发性能,尤其在处理耗时操作时。本文将详细介绍如何使用`@Async`结合`Future`来处理异步任务,并探讨如何定义超时。 `@Async...
Spring Boot 框架提供了 @Async 注解来支持异步任务执行,该注解可以将方法调用转换为异步调用,从而提高应用程序的并发能力和响应速度。下面是关于 Spring Boot @Async 异步任务执行方法的详细知识点: 1. ...
在Spring Boot中,启用...总结起来,Spring Boot中的异步调用通过`@Async`注解实现,可以显著提高应用的响应速度,特别是在处理耗时任务时。同时,合理的线程池配置和异常处理策略是确保异步功能高效、稳定运行的关键。
Spring Boot中实现异步调用的核心在于`@Async`注解。这个注解可以应用在方法上,表明该方法应被异步执行。为了启用Spring Boot的异步支持,我们需要在主配置类(通常为包含`@SpringBootApplication`注解的类)上添加...
在高并发的Web应用中,提高接口的并发处理能力是至关重要的,而SpringBoot框架提供了一种简单有效的方法——使用`@Async`注解来实现异步调用,从而优化性能。本文将深入探讨什么是异步调用,以及如何在SpringBoot中...
Spring Boot 提供了 @Async 注解,可以将方法异步化,使得方法的调用者不需要等待方法的执行结果,直接返回,而方法的实际执行将提交给 Spring 的 TaskExecutor 中,由指定的线程池中的线程执行。 2. TaskExecutor...
Spring Boot @Async 异步方法是 Spring Boot 框架中的一种异步编程方式,允许开发者在不阻塞主线程的情况下执行高耗时方法。下面将详细介绍 Spring Boot @Async 异步方法的使用和原理。 什么是异步调用 异步调用是...
在Spring Boot应用中,使用`@Async`注解可以方便地实现异步任务,而`ThreadPoolTaskScheduler`作为Spring提供的一个任务调度器,允许我们创建一个定制化的线程池来处理这些异步任务。本文将深入探讨如何优雅地关闭`...
SpringBoot框架提供了强大的功能来实现定时任务和异步调用,这在业务场景中非常常见。例如,在电商平台中,需要定时发送邮件、短信、统计监控数据等操作,而在订单流程中,需要异步调用下单、发货通知、短信推送、...
在Java中,Spring框架通过`@Async`注解提供了一种声明式的方法来实现异步调用。 1. **启用异步支持**:要在Spring Boot项目中使用异步方法,首先需要启用异步支持。这可以通过在配置类上添加`@EnableAsync`注解完成...
Spring Boot 多线程 Demo Spring Boot 中使用多线程的方式有很多种,最简单的方式就是使用 @...使用 @Async 注解可以非常方便地实现多线程编程,在 Spring Boot 中使用 @Async 注解可以很容易地实现异步方法的调用。
在Spring Boot中,可以利用`@Async`注解实现异步调用,提高系统性能。但需要注意,Dubbo本身并不支持异步调用,如果需要在Spring Boot中实现异步调用Dubbo服务,通常需要自定义拦截器或采用消息中间件等方式进行改造...
在Spring Boot框架中,异步处理是提升应用性能的关键特性之一。它允许应用程序在不阻塞主线程的情况下执行耗时的操作,从而提高响应速度。在给定的"spring-boot-async-test.zip"压缩包中,包含了一个示例,演示了两...
7. **@Async 实现异步调用**:使用`@Async`注解,开发者可以创建异步方法,提高应用程序的并发性能。这对于长时间运行的任务尤其有用,因为它不会阻塞主线程。 8. **日志管理**:Spring Boot 默认集成了Logback或...