在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) + "毫秒");
    }

}

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

相关推荐
程序员黑豆16 分钟前
Java中怎么实现字符串拼接呢【AI全栈开发】
java
小白学大数据18 分钟前
线上故障急救:依托 OpenClaw 日志排查 403 和 503 问题
爬虫·python·selenium·数据分析
databook1 小时前
用SymPy自动因式分解:从面积拼图到代数恒等式
python·数学·动效
java1234_小锋1 小时前
LangChain4j 开发Java Agent智能体- 多模态支持
java·开发语言·langchain4j
艳阳天_.1 小时前
星瀚弹框页面实现
java·前端·python
kernelcraft1 小时前
Boto3:Python 操作 AWS 的官方 SDK
开发语言·python·其他·aws
D3bugRealm1 小时前
cryptography:Python 开发者的加密标准库
开发语言·python·其他
HappyAcmen2 小时前
5.通义向量模型调用
python
小熊美家熊猫系统2 小时前
电子合同技术实现与合规实践
java·开发语言·分布式