java多线程-8(CompletableFuture的简单使用)

CompletableFuture简单使用

在JDK1.5引入的Future接口表示了一个异步计算返回的结果。但是使用Future获取异步返回结果的时候,要么调用阻塞方法get()方法。要么轮询看isDone()是否为true。get()方法会阻塞其他线程,轮询会耗费CPU的资源。jdk1.8新增的CompletableFuture类是对Future接口的扩展实现,主要为了弥补Future没有回调机制的缺点。

CompletableFuture

4种创建CompletableFuture的方法

  • runAsync(Runnable runnable) 返回一个新的CompletableFuture,使用ForkJoinPool.commonPool()作为它的线程池执行异步代码。
  • runAsync(Runnable runnable, Executor executor)返回一个新的CompletableFuture,使用指定的线程池执行异步代码。
  • supplyAsync(Supplier<U> supplier)返回一个新的CompletableFuture,使用ForkJoinPool.commonPool()作为它的线程池执行异步代码。
  • supplyAsync(Supplier<U> supplier, Executor executor) 返回一个新的CompletableFuture,使用指定的线程池运行异步代码。

==runAsync和supplyAsync的区别在在于runAdync创建的CompletableFuture没有返回值,而supplyAsync有。==如下:

public static void main(String[] args) {
    CompletableFuture.runAsync(()-> System.out.println("嗷嗷嗷"));
    CompletableFuture.supplyAsync(()-> "嘿嘿嘿");
}

CompletableFuture示例

public class FutureDemo3 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = new CompletableFuture<>();
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        executorService.execute(()->{
            try {
                TimeUnit.SECONDS.sleep(5);
                String name="张三";
                completableFuture.complete(name);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        CompletableFuture<String> completableFuture1 = completableFuture.whenComplete((res, throwable) -> {
            System.out.println("异步任务完成,结果为" + res);
        });
        CompletableFuture<Integer> completableFuture2 = completableFuture1.thenApply((s) -> {
            System.out.println("当异步任务执行完成后,根据上一次的异步任务结果,继续开始一个新的异步任务");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return  s.length();
        });
        System.out.println("主线程");
        System.out.println("阻塞方式获得执行结果"+completableFuture2.get());
        System.out.println("主线程");
        executorService.shutdown();
    }
}

CompletableFuture的常用方法

public class Demo{
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newCachedThreadPool();

         CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> "嘿嘿嘿", executorService);
        CompletableFuture<Void> completableFuture1 = CompletableFuture.supplyAsync(() -> {
            try{
                System.out.println("异常线程正在执行中");
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        },executorService)
                .thenApply(res -> { //将上个任务的返回值作为入参传递到该方法中、
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.out.println(res);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return res+1;})
                .thenApplyAsync(res -> {  //与thenApply相比。会将任务提交到线程池找中异步执行,可能由另一个线程执行
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.out.println(res);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    return res * 2;})
                .thenCombine(completableFuture,(s1,s2) -> s1+s2)//合并两个异步任务的返回结果
                .thenAccept((res) -> { //接受上个任务的返回值作为入参。但是无返回值。
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.out.println(res);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    })
                .thenRun(()->{ //既无入参,也无返回值
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.out.println("嘿嘿嘿");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        executorService.shutdown();
                    }
                   });

        System.out.println("主线程结束");
    }
}

打印结果

异常线程正在执行中
主线程结束
1
2
4嘿嘿嘿
嘿嘿嘿

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值