我是靠谱客的博主 无辜小刺猬,这篇文章主要介绍JDK8-11-CompletableFuture(3)- 异常处理,completeExceptionally使用(如何让主线程捕获其他线程产生的异常)JDK8-11-CompletableFuture(3)- 异常处理,现在分享给大家,希望可以做个参考。

JDK8-11-CompletableFuture(3)- 异常处理

承接上文

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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); } }

运行结果:

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

completeExceptionally 方法使用

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

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 线程产生的异常已经被主线程捕获

最后

以上就是无辜小刺猬最近收集整理的关于JDK8-11-CompletableFuture(3)- 异常处理,completeExceptionally使用(如何让主线程捕获其他线程产生的异常)JDK8-11-CompletableFuture(3)- 异常处理的全部内容,更多相关JDK8-11-CompletableFuture(3)-内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(83)

评论列表共有 0 条评论

立即
投稿
返回
顶部