异步调用是处理高并发web应用性能问题的万金油。
同步调用:
@Component
public class Test1 {
private static Random random = new Random();
public void taskOne() throws Exception{
System.out.println("开始做任务1..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务1 time:"+(end-start));
}
public void taskTwo() throws Exception{
System.out.println("开始做任务1..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务1 time:"+(end-start));
}
public void taskThree() throws Exception{
System.out.println("开始做任务1..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务1 time:"+(end-start));
}
}
任务一、任务二、任务三 顺序的执行完了,换言之 taskOne 、taskTwo、taskThree三个函数是顺序执行的。
上述的同步执行调用虽然顺利的执行完了三个任务,但是可以看到执行时间比较长,若这三个任务本身之间不存在依赖关系,可以并发执行的话,同步调用在执行效率方面就比较差,可以考虑通过异步调用的方式来并发执行。
在Spring boot中,我们只需要通过使用@Async注解就能简单的将原本的同步函数变成异步函数,task类改为如下模式。
package com.example.demo.aa;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.Random;
import java.util.concurrent.Future;
@Component
public class Test2 {
private static Random random = new Random();
@Async
public Future<String> taskOne() throws Exception{
System.out.println("开始做任务1..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务1 time:"+(end-start));
return new AsyncResult<>("任务1完成");
}
@Async
public Future<String> taskTwo() throws Exception{
System.out.println("开始做任务2..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务2 time:"+(end-start));
return new AsyncResult<>("任务2完成");
}
@Async
public Future<String> taskThree() throws Exception{
System.out.println("开始做任务3..。");
long start = System.currentTimeMillis();
Thread.sleep(random.nextInt(10000));
long end = System.currentTimeMillis();
System.out.println("结束做任务3 time:"+(end-start));
return new AsyncResult<>("任务3完成");
}
}
为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsync,如下所示
@SpringBootApplication
@EnableAsync
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
测试
@Test
void test2() throws Exception{
long start = System.currentTimeMillis();
Future<String> taskOne = test2.taskOne();
Future<String> taskTwo = test2.taskTwo();
Future<String> taskThree = test2.taskThree();
while (true){
if (taskOne.isDone() && taskTwo.isDone() && taskThree.isDone()){
break;
}
Thread.sleep(1000);
}
long end = System.currentTimeMillis();
System.out.println("任务全部完成,总用时:"+(end-start));
}
开始做任务3..。
开始做任务2..。
开始做任务1..。
结束做任务3 time:3205
结束做任务2 time:4112
结束做任务1 time:6142
任务全部完成,总用时:7023
版权声明:本文为qq_20768305原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。