CompletableFuture.supplyAsync(
()->String.format("%s price: %.2f", shop.getName(), shop.getPrice(shop.getName()))
,executor)
这时,执行9个商品时,执行速度只有1秒。 执行18个商品时也是1秒。这种状态会一直持续,直到商店的数目达到我们之前计算的阀值。 处理需要大量使用异步操作的情况时,这几乎是最有效的策略。
对多个异步任务进行流水线操作
我们在商品中增加一个枚举Discount.Code 来代表每个商品对应不同的折扣率,创建枚举如下:
public class Discount {
public enum Code{
NONE(0),
SILVER(5),
GOLD(10),
PLATINUM(15),
DIAMOND(20);
private final int value;
Code(int value){
this.value = value;
}
}
}
现在我们修改 getPrice方法的返回格式为:ShopName:price:DiscountCode 使用 : 进行分割的返回值。
public String getPrice(String product){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Double price = new Random().nextDouble() * product.charAt(0) + product.charAt(1);
Discount.Code code = Discount.Code.values()[new Random().nextInt(Discount.Code.values().length)];
return String.format("%s:%.2f:%s",name,price,code);
}
返回值: one:120.10:GOLDD
将返回结果封装到 Quote 类中:
public class Quote {
private final String shopName;
private final double price;
private final Discount.Code discountCode;
public Quote(String shopName, double price, Discount.Code code) {
this.shopName = shopName;
this.price = price;
this.discountCode = code;
}
public static Quote parse(String s) {
String[] split = s.split(":");
String shopName = split[0];
double price = Double.parseDouble(split[1]);
Discount.Code discountCode = Discount.Code.valueOf(split[2]);
return new Quote(shopName, price, discountCode);
}
public String getShopName() {
return shopName;
}
public double getPrice() {
return price;
}
public Discount.Code getDiscountCode() {
return discountCode;
}
}
parse方法 通过getPrice的方法 返回的字符串 会返回Quote对象,此外 Discount服务还提供了一个applyDiscount方法,它接收一个Quote对象,返回一个字符串,表示该Quote的shop中的折扣价格:
public class Discount {
public enum Code{..
}
public static String applyDiscount(Quote quote){
return quote.getShopName() + "price :" + Discount.apply(quote.getPrice() ,quote.getDiscountCode());
}
public static double apply(double price,Code code){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return price * (100 - code.value) / 100;
}
}
Discount中 也模拟了远程操作 睡了1秒钟,首先我们尝试最直接的方式:
List<String> str = shops.stream()
.map(shop->shop.getPrice("hhhhh")) //获取 one:120.10:GOLDD 格式字符串
.map(Quote::parse) //转换为 Quote 对象
.map(Discount::applyDiscount) //返回 Quote的shop中的折扣价格
.collect(toList());
System.out.print(str);
8146
首先,我们调用getPrice远程方法将shop对象转换成了一个字符串。每个1秒
然后,我们将字符串转换为Quote对象。
最后,我们将Quote对象 调用 远程 Discount服务获取折扣,返回折扣价格。每个1秒