美文网首页
CompletableFuture(3)- 异常处理,compl

CompletableFuture(3)- 异常处理,compl

作者: zhengaoly | 来源:发表于2023-02-09 13:56 被阅读0次

JDK8-11-CompletableFuture(3)- 异常处理,completeExceptionally使用(如何让主线程捕获其他线程产生的异常)

JDK8-11-CompletableFuture(3)- 异常处理
承接上文

对之前例子中的 calculatePrice 方法进行些许改造,当product传入空值时抛出“无效商品” 的异常:

public class Shop2 {

    private static final Random random = new Random();

    public double calculatePrice(String product) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if (product== null || "".equals(product)) {
            throw new RuntimeException("无效的商品");
        }
        return random.nextDouble() * product.charAt(0);
    }


    public Future<Double> getPriceAsync(String product) {
        //创建 CompletableFuture 对象,对象中包含异步计算结果
        CompletableFuture<Double> futurePrice = new CompletableFuture<>();
        //新建线程计算商品价格
        new Thread(() -> {
            double price = calculatePrice(product);
            //将异步计算得到的结果设置到 CompletableFuture 中,
            futurePrice.complete(price);
        }).start();
        //无需等待计算结果,直接返回 CompletableFuture 对象
        return futurePrice;
    }

    public static void getPriceAsyncTest(String product) {
        long start = System.currentTimeMillis();
        Future<Double> priceFuture = new Shop2().getPriceAsync(product);
        System.out.println(Thread.currentThread() + " 开始做其他事情。。。");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            System.out.println(priceFuture.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }

    public static void main(String[] args) {
        getPriceAsyncTest(null);
    }

}

运行结果:


image.png

注意看,由于传入空名称的产品,程序产生异常,产生异常的线程名为 Thread-0,而程序并没有结束,主线程任然阻塞在 get 方法这里,如果不进行其他处理,程序会一直阻塞

completeExceptionally 方法使用
主线程可以使用有超时时间参数的重载get方法来避免一直阻塞,虽然这是一种推荐并且有用的做法,但是这样主线程并不能得知产生超时异常的具体原因
下面通过改造 getPriceAsync 方法让主线程可以捕获其他线程产生的异常,具体如下:

在 calculatePrice 方法调用处加上try/catch,并调用
futurePrice.completeExceptionally(e);

public Future<Double> getPriceAsync(String product) {
        //创建 CompletableFuture 对象,对象中包含异步计算结果
        CompletableFuture<Double> futurePrice = new CompletableFuture<>();
        //新建线程计算商品价格
        new Thread(() -> {
            try {
                double price = calculatePrice(product);
                //将异步计算得到的结果设置到 CompletableFuture 中,
                futurePrice.complete(price);
            } catch (Exception e) {
                futurePrice.completeExceptionally(e);
            }
        }).start();
        //无需等待计算结果,直接返回 CompletableFuture 对象
        return futurePrice;
    }

再看程序执行结果:

产生 ExecutionException 异常,说明 Thread-0 线程产生的异常已经被主线程捕获


image.png

相关文章

  • Kotlin语言(八):异常处理

    1、空值处理 2、编译异常处理 3、运行时异常

  • 运维少年系列 python and cisco (3)

    运维少年系列 python and cisco (3) 异常处理 什么是异常处理? 异常处理通常来说是对程序在执行...

  • 异常处理

    目录 1.异常处理 2.处理异常的方法 3.自定义异常类 4.断言

  • CompletableFuture及 在stream应用

    直接上代码 执行结果如下: CompletableFuture 1 )多步处理返回future 2 )处理后消费 ...

  • day19

    1:异常(理解) (1)程序出现的不正常的情况。 (2)异常的体系 (3)异常的处理: A:JVM的默认处理把异常...

  • 异常处理

    1 异常处理 2. throw关键字 3. error类型 4. 异常的处理 异常处理有两种方式,一种是不处理,一...

  • Python异常处理(个人笔记)

    Python3 异常处理 捕获全部异常 各种异常清单 抛出异常 若想知道是否抛出了异常

  • Spring Boot 2 Webflux的全局异常处理

    SpringMVC的异常处理 Spring 统一异常处理有 3 种方式,分别为: 使用@ExceptionHand...

  • 管理信息系统

    1.目的 2.异常处理 2.1 常见异常 2.2 异常处理使用 自定义异常image.png 3. 程序模块的封装...

  • koa-异常处理、日志

    一、异常处理 1、安装 npm i koa-onerror -S 2、配置异常处理 3、app.js 404设置 ...

网友评论

      本文标题:CompletableFuture(3)- 异常处理,compl

      本文链接:https://www.haomeiwen.com/subject/acthkdtx.html