多线程中使用CompletableFuture

使用Future获得异步执行结果时,要么调用阻塞方法get(),要么轮询看isDone()是否为true,这两种方法都不是很好,因为主线程也会被迫等待。
从Java 8开始引入了CompletableFuture,它针对Future做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。

public class TestAsync {
    public static void main(String[] args) throws Exception {
        // 创建异步执行任务:
        //第一种调用方法
        CompletableFuture<Double> cf = CompletableFuture.supplyAsync(TestAsync::fetchPrice);
        //第二种调用方法
        CompletableFuture<Double> df = CompletableFuture.supplyAsync(() ->{
           return fetchPrice();
        });
        // 如果执行成功:
        cf.thenAccept((result) -> {
            System.out.println("price: " + result);
        });
        // 如果执行异常:
        cf.exceptionally((e) -> {
            e.printStackTrace();
            return null;
        });
        // 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
        Thread.sleep(5000);
    }

    static Double fetchPrice() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
        }
        if (Math.random() < 0.3) {
            throw new RuntimeException("fetch price failed!");
        }
        return 5 + Math.random() * 20;
    }
}

 

posted @ 2021-03-25 16:12  表演给自己看的认真  阅读(104)  评论(0编辑  收藏  举报