在使用异步注解之前,我们需要先了解,什么是异步调用?
异步调用对应的事同步调用,同步调用是值程序按照我们定义的顺序依次执行,每一行程序都必须等待上一行的程序执行完成之后才执行,而异步是指在顺序执行的时候,不等待异步调用的语句返回结果就执行后面的程序,例如,我们常常进行对报表的导出,因为数据导出需要时间,为了避免用户在界面等待时间过长,我们就会采用异步进行导出。
我们来对比一下同步导出和异步导出的案例:
@Slf4j
@Component
public class AsyncTasks {public static Random random = new Random();//@Asyncpublic CompletableFuture<String> doTaskOne() throws Exception {log.info("开始做任务一");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务一,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务一完成");}//@Asyncpublic CompletableFuture<String> doTaskTwo() throws Exception {log.info("开始做任务二");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务二,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务二完成");}//@Asyncpublic CompletableFuture<String> doTaskThree() throws Exception {log.info("开始做任务三");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务三,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务三完成");}}
在我们的测试类中执行三个函数方法,
@Slf4j
@SpringBootTest
public class ApplicationTests {@Autowiredprivate AsyncTasks asyncTasks;@Testpublic void test() throws Exception {asyncTasks.doTaskOne();asyncTasks.doTaskTwo();asyncTasks.doTaskThree();}}
异步调用:
@Slf4j
@Component
public class AsyncTasks {public static Random random = new Random();@Asyncpublic CompletableFuture<String> doTaskOne() throws Exception {log.info("开始做任务一");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务一,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务一完成");}@Asyncpublic CompletableFuture<String> doTaskTwo() throws Exception {log.info("开始做任务二");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务二,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务二完成");}@Asyncpublic CompletableFuture<String> doTaskThree() throws Exception {log.info("开始做任务三");long start = System.currentTimeMillis();Thread.sleep(random.nextInt(10000));long end = System.currentTimeMillis();log.info("完成任务三,耗时:" + (end - start) + "毫秒");return CompletableFuture.completedFuture("任务三完成");}}
@Slf4j
@SpringBootTest
public class ApplicationTests {@Autowiredprivate AsyncTasks asyncTasks;@Testpublic void test() throws Exception {long start = System.currentTimeMillis();CompletableFuture<String> task1 = asyncTasks.doTaskOne();CompletableFuture<String> task2 = asyncTasks.doTaskTwo();CompletableFuture<String> task3 = asyncTasks.doTaskThree();CompletableFuture.allOf(task1, task2, task3).join();long end = System.currentTimeMillis();log.info("任务全部完成,总耗时:" + (end - start) + "毫秒");}}
注意,异步调用的结果是随机的,你的结果和我这边的结果不一样很正常。