在Spring Boot中使用@Async实现一个异步调用

在使用异步注解之前,我们需要先了解,什么是异步调用?

异步调用对应的事同步调用,同步调用是值程序按照我们定义的顺序依次执行,每一行程序都必须等待上一行的程序执行完成之后才执行,而异步是指在顺序执行的时候,不等待异步调用的语句返回结果就执行后面的程序,例如,我们常常进行对报表的导出,因为数据导出需要时间,为了避免用户在界面等待时间过长,我们就会采用异步进行导出。

我们来对比一下同步导出和异步导出的案例:

java 复制代码
@Slf4j
@Component
public class AsyncTasks {

    public static Random random = new Random();

    //@Async
    public 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("任务一完成");
    }

    //@Async
    public 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("任务二完成");
    }

    //@Async
    public 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("任务三完成");
    }

}

在我们的测试类中执行三个函数方法,

java 复制代码
@Slf4j
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private AsyncTasks asyncTasks;

    @Test
    public void test() throws Exception {
        asyncTasks.doTaskOne();
        asyncTasks.doTaskTwo();
        asyncTasks.doTaskThree();
    }

}

异步调用:

java 复制代码
@Slf4j
@Component
public class AsyncTasks {

    public static Random random = new Random();

    @Async
    public 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("任务一完成");
    }

    @Async
    public 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("任务二完成");
    }

    @Async
    public 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("任务三完成");
    }

}
java 复制代码
@Slf4j
@SpringBootTest
public class ApplicationTests {

    @Autowired
    private AsyncTasks asyncTasks;

    @Test
    public 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) + "毫秒");
    }

}

注意,异步调用的结果是随机的,你的结果和我这边的结果不一样很正常。

相关推荐
__lost21 分钟前
Python图像变清晰与锐化,调整对比度,高斯滤波除躁,卷积锐化,中值滤波钝化,神经网络变清晰
python·opencv·计算机视觉
A阳俊yi22 分钟前
Spring Boot日志配置
java·spring boot·后端
苹果酱056722 分钟前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
海绵波波10726 分钟前
玉米产量遥感估产系统的开发实践(持续迭代与更新)
python·flask
斜月33 分钟前
一个服务预约系统该如何设计?
spring boot·后端
echo1754251 小时前
Apipost免费版、企业版和私有化部署详解
java
逢生博客1 小时前
使用 Python 项目管理工具 uv 快速创建 MCP 服务(Cherry Studio、Trae 添加 MCP 服务)
python·sqlite·uv·deepseek·trae·cherry studio·mcp服务
异常君1 小时前
Java 高并发编程:等值判断的隐患与如何精确控制线程状态
java·后端·代码规范
异常君1 小时前
Java 日期处理:SimpleDateFormat 线程安全问题及解决方案
java·后端·代码规范
都叫我大帅哥1 小时前
Spring AI中的ChatClient:从入门到精通,一篇搞定!
java·spring·ai编程