Java8使用CompletableFuture实现多异步任务同步等待结果

一、应用场景

在实际的开发工作中,我们可能会遇到一些比较复杂且耗时的功能,例如一个业务数据表格的导出,假定业务数据表本身都很大,需要组装的数据又比较多,就会造成整个实现过程很耗时甚至可能出现接口请求超时;这个时候我们会想到把过程中耗时的查询和数据处理通过异步的方式来提升执行效率,但一些查询数据的组装需要等待结果再进行下一步处理,这个时候就要用到Java8引入的新特性:CompletableFuture

二、使用方法

假设现在有个接口,其中有3个比较耗时的查询:getSomething1()、getSomething2()、getSomething3();同步执行所需的时间即3个查询所需时间之和;使用CompletableFuture实现异步执行,等待所有查询结果,所需时间则为3个查询中最大的时间, 如下的示例中,3个查询共需要6秒,使用CompletableFuture优化后仅需3秒!

特别提醒:在使用CompletableFuture启动线程去执行任务后,切忌立马下一行调用get()方法,这样会阻塞线程,会导致多个CompletableFuture任务之间挨个等待,又变回同步执行了!

java 复制代码
import cn.hutool.core.date.DateUtil;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class CompletableFutureTest {


    public static void main(String[] args) throws InterruptedException, ExecutionException {

        System.out.println("同步执行任务开始时间:" + DateUtil.now());
        String something1 = getSomething1();
        String something2 = getSomething2();
        String something3 = getSomething3();

        System.out.println("getSomething1() : " + something1);
        System.out.println("getSomething2() : " + something2);
        System.out.println("getSomething3() : " + something3);
        System.out.println("同步执行任务结束时间:" + DateUtil.now());

        System.out.println();

        System.out.println("异步执行任务开始时间:" + DateUtil.now());
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(CompletableFutureTest::getSomething1);
        CompletableFuture<String> cf2 = CompletableFuture.supplyAsync(CompletableFutureTest::getSomething2);
        CompletableFuture<String> cf3 = CompletableFuture.supplyAsync(CompletableFutureTest::getSomething3);
        System.out.println("getSomething1() : " + cf1.get());
        System.out.println("getSomething2() : " + cf2.get());
        System.out.println("getSomething3() : " + cf3.get());
        System.out.println("异步执行任务结束时间:" + DateUtil.now());




    }


    public static String getSomething1()  {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "getSomething1";
    }

    public static String getSomething2()  {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "getSomething2";
    }

    public static String getSomething3() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "getSomething3";
    }


}

控制台执行结果:

​​​​​​​

在实际开发中使用,推荐使用线程池去执行异步任务,supplyAsync()重载的方法中有支持线程池对象参数,快去体验吧!

相关推荐
无休居士23 天前
Java8中CompletableFuture.allOf的使用
android·java·开发语言·future·completable·allof
iFlyCai3 个月前
Flutter中的异步编程
flutter·stream·async·future·await·futurebuilder·flutter异步编程
-无-为-4 个月前
科普文:JUC系列之Java异步执行器CompletableFuture源码解读
java·大数据·python·future·completable
lpruoyu5 个月前
【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【15】异步_线程池
线程池·completable·异步
许野平5 个月前
Rust:Future、async 异步代码机制示例与分析
rust·进程·并发·async·future·异步·并行
涵哥爱编程6 个月前
CompletableFuture详细讲解
java·数据库·并发·future·并发编程·completable
许野平6 个月前
Rust的协程机制:原理与简单示例
rust·async·future·协程·await
进朱者赤7 个月前
Java8 CompletableFuture:异步编程的瑞士军刀
java·future·completable·java8·juc·future模式
AI架构师易筋9 个月前
Swift Combine 有序的异步操作 从入门到精通十二
ios·swift·future·combine·sink
AI架构师易筋9 个月前
Swift Combine 用 Future 来封装异步请求 从入门到精通十一
开发语言·ios·swift·future·promise·combine