什么是异步调用?
异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行。
如何实现异步调用?
- 多线程,这是很多人第一眼想到的关键词,没错,多线程就是一种实现异步调用的方式。
- 在非spring目项目中我们要实现异步调用的就是使用多线程方式,可以自己实现Runable接口或者集成Thread类,或者使用jdk1.5以上提供了的Executors线程池。
- StrngBoot中则提供了很方便的方式执行异步调用。
异步接口的使用场景
耗时比较长,任务比较多的接口。比方说,文件下载,大文件下载比较耗时,这个时候就可以使用异步接口。
示例
maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
启动类:添加@EnableAsync注解
@SpringBootApplication
@EnableAsync
public class SpringbootAsyncApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootAsyncApplication.class, args);
}
}
异步任务类
package com.sumeng.springboot.config;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
@Component
public class AsyncProperties {
@Async
public Future<String> taskOne() throws InterruptedException {
Long start = System.currentTimeMillis();
Thread.sleep(1000);
Long end = System.currentTimeMillis();
System.out.println("taskOne耗时:"+(end-start)+"ms");
return new AsyncResult<String>("taskOne执行完毕!!!");
}
@Async
public Future<String> taskOtwo() throws InterruptedException {
Long start = System.currentTimeMillis();
Thread.sleep(1000);
Long end = System.currentTimeMillis();
System.out.println("tasktwo耗时:"+(end-start)+"ms");
return new AsyncResult<String>("tasktwo执行完毕!!!");
}
@Async
public Future<String> taskThree() throws InterruptedException {
Long start = System.currentTimeMillis();
Thread.sleep(1000);
Long end = System.currentTimeMillis();
System.out.println("taskThree耗时:"+(end-start)+"ms");
return new AsyncResult<String>("taskThree执行完毕!!!");
}
}
controller
package com.sumeng.springboot.controller;
import com.sumeng.springboot.config.AsyncProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;
@RestController
public class AsyncController {
@Autowired
private AsyncProperties asyncProperties;
@GetMapping("/task")
public String dotask() throws InterruptedException {
Long start = System.currentTimeMillis();
Future<String> one = asyncProperties.taskOne();
Future<String> two = asyncProperties.taskOtwo();
Future<String> three = asyncProperties.taskThree();
String result = null;
for(;;){
if (one.isDone() && two.isDone() && three.isDone()){
break;
}
Thread.sleep(1000);
}
Long end = System.currentTimeMillis();
result = "task总耗时:"+(end - start)+"ms";
System.out.println("task总耗时:"+result);
return result;
}
}
控制台输出
tasktwo耗时:1000ms
taskOne耗时:1000ms
taskThree耗时:1000ms
task总耗时:task总耗时:2001ms
浏览器输出
异步调用成功,并且在所有任务都完成时程序才返回了结果!