关于Java类Compeletable的使用

Future是Java 5添加的类,用来描述一个异步计算的结果。你可以使用isDone方法检查计算是否完成,或者使用get阻塞住调用线程,直到计算完成返回结果,你也可以使用cancel方法停止任务的执行。

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

创建异步对象

CompletableFuture 提供了四个静态方法来创建一个异步操作:
在这里插入图片描述
没有指定Executor的方法会使用ForkJoinPool.commonPool() 作为它的线程池执行异步代码。如果指定线程池,则使用指定的线程池运行。以下所有的方法都类同。

runAsync方法不支持返回值

    @Test
    public void test1()
       {
//        创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        System.out.println("主线程运行中-");
        //        CompleteableFuture创建异步对象
        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
            System.out.println("当前线程:"+Thread.currentThread().getName());
            int result=1024;
            System.out.println("result:"+result);
        }, executorService);
        System.out.println("main over");
    }

supplyAsync可以支持返回值。


    @Test
    public void tset2() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        
        System.out.println("main begin");
        
        CompletableFuture<Integer> completableFuture= CompletableFuture.supplyAsync(()->{
            System.out.println("当前线程:"+Thread.currentThread().getName());
            int value=1024;
            System.out.println("value:"+value);
            return value;
        },executorService);

        Integer integer = completableFuture.get();
        System.out.println("main  value+"+integer);


    }

计算完成时回调方法

在这里插入图片描述
whenComplete可以处理正常或异常的计算结果,exceptionally处理异常情况。BiConsumer<? super T,? super Throwable>可以定义处理业务

whenComplete 和 whenCompleteAsync 的区别:

whenComplete:是执行当前任务的线程执行继续执行 whenComplete 的任务。
whenCompleteAsync:是执行把 whenCompleteAsync 这个任务继续提交给线程池来进行执行。
方法不以Async结尾,意味着Action使用相同的线程执行,而Async可能会使用其他线程执行(如果是使用相同的线程池,也可能会被同一个线程选中执行)

    @Test
    public void test3(){
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        System.out.println("main begin");

        CompletableFuture<Integer> uCompletableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程:"+Thread.currentThread().getName());
            int result=1024/0;
            System.out.println("result:"+result);
            return result;
        }, executorService).whenComplete((rs,exception)->{
            System.out.println("接收到的返回值:"+rs);
            System.out.println("接收到的异常:"+exception);
        });

        System.out.println("main over");
    }

线程串行化方法

thenApply 方法:当一个线程依赖另一个线程时,获取上一个任务返回的结果,并返回当前任务的返回值。
在这里插入图片描述
thenAccept方法:消费处理结果。接收任务的处理结果,并消费处理,无返回结果
在这里插入图片描述
thenRun方法:只要上面的任务执行完成,就开始执行thenRun,只是处理完任务后,执行 thenRun的后续操作
在这里插入图片描述

带有Async默认是异步执行的。这里所谓的异步指的是不在当前线程内执行。

串行化代码演示:

 @Test
    public void test4(){

        ExecutorService executorService = Executors.newFixedThreadPool(3);

//        任务1,返回结果是100
        CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> {
            int res=100;
            System.out.println("线程一:"+res);
            return res;
        }, executorService);

//        任务2,获取任务1的返回结果
        CompletableFuture<Integer> futureB=futureA.thenApplyAsync((res)->{
            System.out.println("线程二:"+res);
            return res;
        },executorService);

//      线程3:无法获取futureA返回结果
        CompletableFuture<Void> futureC=futureA.thenRunAsync(()->{
            System.out.println("线程三。。。");
        },executorService);


    }

多任务组合

public static CompletableFuture<Void> allOf(CompletableFuture<?>... cfs);

public static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs);

allOf:等待所有任务完成
anyOf:只要有一个任务完成

allOf:

    @Test
    public void test5() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);

//        线程1
        CompletableFuture<Integer> futureA=
                CompletableFuture.supplyAsync(()->{
                    System.out.println(Thread.currentThread().getName()+"--begin");
                    int res=100;
                    for (int i = 0; i < 100; i++) {
                        res++;
                    }
                    System.out.println("线程一:"+res);
                    System.out.println(Thread.currentThread().getName()+"--over");
                    return res;
            },executorService);


//        线程二
        CompletableFuture<Integer> futureB=
                CompletableFuture.supplyAsync(()->{
                    System.out.println(Thread.currentThread().getName()+"--begin");
                    int res=30;
                    for (int i = 0; i <100000 ; i++) {
                        res++;
                    }
                    System.out.println("线程二:"+res);
                    System.out.println(Thread.currentThread().getName()+"--over");
                    return res;
                },executorService);


//        线程三收集前两个线程
         CompletableFuture<Void> all=CompletableFuture.allOf(futureA,futureB);
         all.get();
         System.out.println("所有线程完毕");

    }

执行结果:

pool-1-thread-1–begin
线程一:200
pool-1-thread-1–over
pool-1-thread-2–begin
线程二:100030
pool-1-thread-2–over
所有线程完毕

anyOf:


    @Test
    public void test6() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        // 线程1
        CompletableFuture<Integer> futureA = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "--begin");
            int res = 100;
            for (int i = 0; i < 100; i++) {
                res++;
            }
            System.out.println("线程一:" + res);
            System.out.println(Thread.currentThread().getName() + "--over");
            return res;
        }, executorService);

        // 线程二
        CompletableFuture<Integer> futureB = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "--begin");
            int res = 30;
            for (int i = 0; i < 1000000000; i++) {
                res++;
            }
            System.out.println("线程二:" + res);
            System.out.println(Thread.currentThread().getName() + "--over");
            return res;
        }, executorService);

        // 线程三等待任意一个线程完成
        CompletableFuture<Object> any = CompletableFuture.anyOf(futureA, futureB);
        any.get(); // 等待任意一个线程完成

        System.out.println("某个线程已完成");
    }

执行结果:

pool-1-thread-1–begin
线程一:200
pool-1-thread-1–over
pool-1-thread-2–begin
某个线程已完成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值