• 正文概述
  • 售后服务
  • CompletableFuture

    Java 8 开始引入了 CompletableFuture,它针对 Future 做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法。

    CompletableFuture 的优点是:

    • 异步任务结束时,会自动回调某个对象的方法;
    • 异步任务出错时,会自动回调某个对象的方法;
    • 主线程设置好回调后,不再关心异步任务的执行。

    public class T {
    
        public static void main(String[] args) throws Exception {
            // 创建异步执行任务:
            CompletableFuture<Double> cf = CompletableFuture.supplyAsync(T::fetchPrice);
            // 如果执行成功:
            cf.thenAccept((result) -> {
                System.out.println("price: " + result);
            });
            // 如果执行异常:
            cf.exceptionally((e) -> {
                e.printStackTrace();
                return null;
            });
            // 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
            Thread.sleep(2000);
        }
    
        static Double fetchPrice() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (Math.random() < 0.3) {
                throw new RuntimeException("fetch price failed!");
            }
            return 5 + Math.random() * 20;
        }
    }
    

    除了实现了异步回调机制外,多个 CompletableFuture 可以串行执行。

    public class T {
    
        public static void main(String[] args) throws Exception {
            // 第一个任务:
            CompletableFuture<String> cfQuery = CompletableFuture.supplyAsync(() -> {
                return queryCode("中国石油");
            });
            // cfQuery成功后继续执行下一个任务:
            CompletableFuture<Double> cfFetch = cfQuery.thenApplyAsync(T::fetchPrice);
            // cfFetch成功后打印结果:
            cfFetch.thenAccept((result) -> {
                System.out.println("price: " + result);
            });
            // 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
            Thread.sleep(2000);
        }
    
        static String queryCode(String name) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
            return "601857";
        }
    
        static Double fetchPrice(String code) {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 5 + Math.random() * 20;
        }
    }
    

    除了串行执行外,多个 CompletableFuture 还可以并行执行。

    public class T {
    
        public static void main(String[] args) throws Exception {
            // 两个CompletableFuture执行异步查询:
            CompletableFuture<String> cfQueryFromSina = CompletableFuture.supplyAsync(() -> {
                return queryCode("中国石油", "https://finance.sina.com.cn/code/");
            });
            CompletableFuture<String> cfQueryFrom163 = CompletableFuture.supplyAsync(() -> {
                return queryCode("中国石油", "https://money.163.com/code/");
            });
    
            // 用anyOf合并为一个新的CompletableFuture:
            CompletableFuture<Object> cfQuery = CompletableFuture.anyOf(cfQueryFromSina, cfQueryFrom163);
    
            // 两个CompletableFuture执行异步查询:
            CompletableFuture<Double> cfFetchFromSina = cfQuery.thenApplyAsync((code) -> {
                return fetchPrice((String) code, "https://finance.sina.com.cn/price/");
            });
            CompletableFuture<Double> cfFetchFrom163 = cfQuery.thenApplyAsync((code) -> {
                return fetchPrice((String) code, "https://money.163.com/price/");
            });
    
            // 用anyOf合并为一个新的CompletableFuture:
            CompletableFuture<Object> cfFetch = CompletableFuture.anyOf(cfFetchFromSina, cfFetchFrom163);
    
            // 最终结果:
            cfFetch.thenAccept((result) -> {
                System.out.println("price: " + result);
            });
            // 主线程不要立刻结束,否则CompletableFuture默认使用的线程池会立刻关闭:
            Thread.sleep(2000);
        }
    
        static String queryCode(String name, String url) {
            System.out.println("query code from " + url + "...");
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "601857";
        }
    
        static Double fetchPrice(String code, String url) {
            System.out.println("query price from " + url + "...");
            try {
                Thread.sleep((long) (Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 5 + Math.random() * 20;
        }
    
    }
    
    本站所提供的部分资源来自于网络,版权争议与本站无关,版权归原创者所有!仅限用于学习和研究目的,不得将上述内容资源用于商业或者非法用途,否则,一切后果请用户自负。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源。如果上述内容资对您的版权或者利益造成损害,请提供相应的资质证明,我们将于3个工作日内予以删除。本站不保证所提供下载的资源的准确性、安全性和完整性,源码仅供下载学习之用!如用于商业或者非法用途,与本站无关,一切后果请用户自负!本站也不承担用户因使用这些下载资源对自己和他人造成任何形式的损失或伤害。如有侵权、不妥之处,请联系站长以便删除!
    金点网络 » Java 并发编程·CompletableFuture

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。
    是否提供免费更新服务?
    持续更新,永久免费
    是否经过安全检测?
    安全无毒,放心食用

    提供最优质的资源集合

    立即加入 友好社区
    ×