并发异步编程CompletableFuture 示例

正文

神奇的CompletableFuture

什么是CompletableFuture

在Java 8中, 新增加了一个包含50个方法左右的类: CompletableFuture,结合了Future的优点,提供了非常强大的Future的扩展功能,可以帮助我们简化异步编程的复杂性,提供了函数式编程的能力,可以通过回调的方式处理计算结果,并且提供了转换和组合CompletableFuture的方法。

CompletableFuture被设计在Java中进行异步编程。异步编程意味着在主线程之外创建一个独立的线程,与主线程分隔开,并在上面运行一个非阻塞的任务,然后通知主线程进展,成功或者失败。

通过这种方式,你的主线程不用为了任务的完成而阻塞/等待,你可以用主线程去并行执行其他的任务。 使用这种并行方式,极大地提升了程序的表现。

并发异步编程CompletableFuture 示例_第1张图片

译文:

当一个Future可能需要显示地完成时,使用CompletionStage接口去支持完成时触发的函数和操作。
当2个以上线程同时尝试完成、异常完成、取消一个CompletableFuture时,只有一个能成功。
 
CompletableFuture实现了CompletionStage接口的如下策略:
 
1.为了完成当前的CompletableFuture接口或者其他完成方法的回调函数的线程,提供了非异步的完成操作。
 
2.没有显式入参Executor的所有async方法都使用ForkJoinPool.commonPool()为了简化监视、调试和跟踪,
    所有生成的异步任务都是标记接口AsynchronousCompletionTask的实例。
 
3.所有的CompletionStage方法都是独立于其他共有方法实现的,因此一个方法的行为不会受到子类中其他
    方法的覆盖。
 
CompletableFuture实现了Futurre接口的如下策略:
 
1.CompletableFuture无法直接控制完成,所以cancel操作被视为是另一种异常完成形式。
    方法isCompletedExceptionally可以用来确定一个CompletableFuture是否以任何异常的方式完成。
 
2.以一个CompletionException为例,方法get()和get(long,TimeUnit)抛出一个ExecutionException,
    对应CompletionException。为了在大多数上下文中简化用法,这个类还定义了方法join()和getNow,
    而不是直接在这些情况中直接抛出CompletionException。

简单小案例:

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture aFuture = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("a人员数钱完毕");
            return 100;
        });
        CompletableFuture bFuture = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(4000);
                System.out.println("b人员数钱完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 300;
        });
        CompletableFuture cFuture = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(5000);
                System.out.println("c人员数钱完毕");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 300;
        });

        System.out.println("开始..." + new Date().toLocaleString());
        //并行处理
        CompletableFuture.allOf(aFuture, bFuture, cFuture).join();

        //取值
        Integer a = aFuture.get();
        Integer b = bFuture.get();
        Integer c = cFuture.get();

        System.out.println(a + b + c);
        System.out.println("结束..." + new Date().toLocaleString());
    }

实战:

//未优化前代码

  @Override
    public IndexBaseInfoVO getBaseInfo(String beginCreateTime, String endCreateTime) {
        //1)构建一个空的结果集对象
        IndexBaseInfoVO result = new IndexBaseInfoVO();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        try {
            //3 封装结果集对象
            result.setCluesNum(reportMpper.getCluesNum(beginCreateTime, endCreateTime, username));
            result.setBusinessNum(reportMpper.getBusinessNum(beginCreateTime, endCreateTime, username));
            result.setContractNum(reportMpper.getContractNum(beginCreateTime, endCreateTime, username));
            result.setSalesAmount(reportMpper.getSalesAmount(beginCreateTime, endCreateTime, username));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        //4 返回结果集对象
        return result;

 优化后代码:

 /*---------------------------------首页基本数据--使用CompletableFuture 技术优化--------------------------------------*/

    @Override
    public IndexBaseInfoVO getBaseInfo(String beginCreateTime, String endCreateTime) {
        //1)构建一个空的结果集对象
        IndexBaseInfoVO result = new IndexBaseInfoVO();
        //2 封装结果集属性
        // 2.1 由于查询需要用到用户名 调用工具类获取用户名
        String username = SecurityUtils.getUsername();
        try {

            CompletableFuture cluesNums = CompletableFuture.supplyAsync(() -> {
                //线索数量
                return reportMpper.getCluesNum(beginCreateTime, endCreateTime, username);

            });

            CompletableFuture businessNum = CompletableFuture.supplyAsync(() -> {
                //商机数量
                return reportMpper.getBusinessNum(beginCreateTime, endCreateTime, username);

            });
            CompletableFuture contractNum = CompletableFuture.supplyAsync(() -> {
                //合同数量
                return reportMpper.getContractNum(beginCreateTime, endCreateTime, username);

            });
            CompletableFuture salesAmount = CompletableFuture.supplyAsync(() -> {
                //销售金额
                return reportMpper.getSalesAmount(beginCreateTime, endCreateTime, username);

            });
            //3. join等待所有线程全部执行完成
            CompletableFuture.
                    allOf(
                            cluesNums,
                            businessNum,
                            contractNum,
                            salesAmount)
                    .join();

            //4.封装结果集对象
            result.setCluesNum(cluesNums.get());
            result.setBusinessNum(businessNum.get());
            result.setContractNum(contractNum.get());
            result.setSalesAmount(salesAmount.get());

        } catch (Exception e) {
            e.printStackTrace();
        }
        //5 返回结果集对象
        return result;
    }

    /*-------------------------------------------代码优化完毕----------------------------------------------------------*/

 

你可能感兴趣的:(java,jvm,开发语言)