《Java8实战》笔记(11):CompletableFuture-组合式异步编程

// 待实现

}

}

模拟1秒钟延迟的方法

public static void delay() {

try {

Thread.sleep(1000L);

} catch (InterruptedException e) {

throw new RuntimeException(e);

}

}

在getPrice方法中引入一个模拟的延迟

public double getPrice(String product) {

return calculatePrice(product);

}

private double calculatePrice(String product) {

delay();

return random.nextDouble() * product.charAt(0) + product.charAt(1);

}

将同步方法转换为异步方法

将getPrice转换为getPriceAsync方法,并修改它的返回值:

public Future getPriceAsync(String product) {

CompletableFuture futurePrice = new CompletableFuture<>();

new Thread( () -> {

double price = calculatePrice(product);

futurePrice.complete(price);

}).start();

//无需等待还没结束的计算,直接返回Future对象

return futurePrice;

}

使用异步API

ShopMain

运行结果

Invocation returned after 43 msecs

Price is 123.26

Price returned after 1045 msecs

错误处理

如果价格计算过程中产生了错误会怎样呢?非常不幸,这种情况下你会得到一个相当糟糕的结果:用于提示错误的异常会被限制在试图计算商品价格的当前线程的范围内,最终会杀死该线程,而这会导致等待get方法返回结果的客户端永久地被阻塞。

客户端可以使用重载版本的get方法,它使用一个超时参数来避免发生这样的情况。使用这种方法至少能防止程序永久地等待下去,超时发生时,程序会得到通知发生了TimeoutException。

为了让客户端能了解商店无法提供请求商品价格的原因,你需要使用CompletableFuture的completeExceptionally方法将导致CompletableFuture内发生问题的异常抛出。

public Future getPriceAsync(String product) {

CompletableFuture futurePrice = new CompletableFuture<>();

new Thread( () -> {

try {

double price = calculatePrice(product);

futurePrice.complete(price);

} catch (Exception ex) {

futurePrice.completeExceptionally(ex);

}

}).start();

return futurePrice;

}

使用工厂方法supplyAsync创建CompletableFuture

CompletableFuture类自身提供了大量精巧的工厂方法,使用这些方法能更容易地完成整个流程,还不用担心实现的细节。

public Future getPriceAsync(String product) {

return CompletableFuture.supplyAsync(() -> calculatePrice(product));

}

让你的代码免受阻塞之苦——将无法改变的同步适配成异步


BestPriceFinder

BestPriceFinderMain

你已经被要求进行“最佳价格查询器”应用的开发了,不过你需要查询的所有商店只提供了同步API。

换句话说,你有一个商家的列表,如下所示:

List shops = Arrays.asList(new Shop(“BestPrice”),

new Shop(“LetsSaveBig”),

new Shop(“MyFavoriteShop”),

new Shop(“BuyItAll”));

采用顺序查询所有商店的方式实现的findPrices方法

public List findPrices(String product) {

return shops.stream()

.map(shop -> String.format(“%s

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值