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

一、应用场景

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

二、使用方法

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

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

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()重载的方法中有支持线程池对象参数,快去体验吧!

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值