【JUC】03-CompletableFuture使用

1. CompletableFuture

 CompletableFuture可以进行回调通知、创建异步任务、多个任务前后依赖可以组合处理、对计算速度选最快。
 CompletableFuture提供了一种类似于观察者模式的通知方式,可以在任务完成后通知监听方。
CompletableFuture实例化用CompletableFuture.runAsync()和CompletableFuture.supplyAsync()。

public class demo04 {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        // 无返回值
//        CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(new MyThread4(), threadPool);
//        try {
//            System.out.println(completableFuture.get());
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        } catch (ExecutionException e) {
//            throw new RuntimeException(e);
//        }

        // 有返回值
        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "Hello World";
        });
        try {
            System.out.println(stringCompletableFuture.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        // 有返回值
        CompletableFuture completableFuture = CompletableFuture.supplyAsync(new MyThread5(), threadPool);
        try {
            System.out.println(completableFuture.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        threadPool.shutdown();
    }
}
class MyThread5 implements Supplier {
    @Override
    public Object get() {
        return "Hello Apple";
    }
}
class MyThread4 implements Runnable {
    @Override
    public void run() {
        try {
            TimeUnit.SECONDS.sleep(3);
            System.out.println("Hello World");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

2. whenCompleted与exceptionally用法

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        
        try {
            CompletableFuture.supplyAsync(()->{
                int num = 10/0;
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                return num;
            }, threadPool).whenComplete((v,e)->{
                if(e == null) {
                    System.out.println("Result is " + v);
                }
            }).exceptionally(e->{
                e.printStackTrace();
                System.out.println(e.getCause() + e.getMessage());
                return null;
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            threadPool.shutdown();
        }
        System.out.println("Main is completed");
    }

在这里插入图片描述
链式调用

public class demo06 {
    public static void main(String[] args){
        Stu stu = new Stu();
        stu.setId("1818").setName("Jack");
        System.out.println(stu.toString());

        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            return "Hello World";
        });
        // 编译时,必须设置对于异常的处理
        try {
            System.out.println(completableFuture.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }

        // 可以不进行设置对于异常的处理
        String join = completableFuture.join();
    }
}

@AllArgsConstructor
@NoArgsConstructor
// 允许链式调用
@Accessors(chain = true)
@Setter
@Getter
@ToString
class Stu {
    private String id;
    private String name;
}

 CompletableFuture的例子。

public class demo07 {
    public static List<ShopMall> list = Arrays.asList( new ShopMall("taobao")
                                ,new ShopMall("jd")
                                ,new ShopMall("pdd")
                                ,new ShopMall("dangdang"));
    public static void main(String[] args){
        System.out.println(extracted("mysql"));
    }

    private static List<String> extracted(String productName) {
        List<String> stringList = list.stream()
                // 使用CompletableFuture实现多线程异步
                .map(shopMall -> CompletableFuture.supplyAsync(() -> String.format(productName + "'s price in %s is %.2f", shopMall.getShop(), shopMall.getPrice(productName))))
                .collect(Collectors.toList()).stream().map(completableFuture -> completableFuture.join()).collect(Collectors.toList());
        return stringList;
    }
}

@AllArgsConstructor
class ShopMall {
    @Getter
    String shop;

    public Double getPrice(String name) {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return ThreadLocalRandom.current().nextDouble()*2 + name.charAt(0);
    }
}

 CompletableFuture的用法:

public class demo08 {
    public static void main(String[] args) {

        CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "Hello World";
        });

        // 需要抛异常
        // System.out.println(completableFuture.get());

        // 无需抛异常
        // System.out.println(completableFuture.join());

        // 子线程没执行完, 就返回getNow的参数
        // System.out.println(completableFuture.getNow("Absent"));

        // 子线程未执行完, complete返回true, join返回complete的参数
        System.out.println(completableFuture.complete("Absent") + ":" + completableFuture.join());
    }
}

3. CompletableFuture常用函数

 对于执行结果的处理。

public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CompletableFuture.supplyAsync(()->{
                    return 1;
        }, threadPool)
                // 前一步结果作为返回值,有异常则停止
                .thenApply(f->{
                    System.out.println("thenApply");
                    return f+1;
                })
                // 可以带着异常,继续执行
//                .handle((v, e)->{
//                    System.out.println("handel");
//                    int num = 10/0;
//                    return v+1;
//                })
                // 无返回值
                .thenAccept(v->{
                    System.out.println("thenAccept");
                    System.out.println(v);
                })
                // 无参数与返回值
                .thenRun(()->{
                    System.out.println("thenRun");
                });
        threadPool.shutdown();
    }

  CompletableFuture异步方法与applyToEither选取执行速度更快的线程。

    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        // thenRunAsync会让后续线程使用默认线程池
        CompletableFuture.supplyAsync(()->{
                    System.out.println(Thread.currentThread().getName());
                    return 1;
        }, threadPool)
                // 前一步结果作为返回值,有异常则停止
                .thenRunAsync(()->{
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("Hello");
                })
                .thenRunAsync(()->{
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("Hello");
                })
                .thenRun(()->{
                    System.out.println(Thread.currentThread().getName());
                    System.out.println("Hello");
                });

        CompletableFuture<String> completableFutureA = CompletableFuture.supplyAsync(() -> {
            System.out.println("A comes in");
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "A";
        });

        CompletableFuture<String> completableFutureB = CompletableFuture.supplyAsync(() -> {
            System.out.println("B comes in");
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "B";
        });

        // 选用执行更快的线程
        CompletableFuture<String> completableFuture = completableFutureA.applyToEither(completableFutureB, v -> {
            return "win is " + v;
        });
        System.out.println(completableFuture.join());
		// 将结果联合
        CompletableFuture<String> combine = completableFutureA.thenCombine(completableFutureB, (a, b) -> {
            return a + b;
        });

        System.out.println(combine.join());

        threadPool.shutdown();
    }
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CRE_MO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值