CompletableFuture,Java 异步编程

  1. 构建异步编程,返回结果
    构建线程池;提交一个Callable并获得Future;取结果,也许会阻塞。
  • 构建线程池;提交一个Callable并获得Future;取结果,也许会阻塞。

在这里插入图片描述

  • 异步执行图
public class Shop {
    public double getPrice(String product) {
	    return calculatePrice(product);
	}
	private double calculatePrice(String product) {
	    delay();
	    return random.nextDouble() * product.charAt(0) + product.charAt(1);
	}

	public static void delay() {
	    try {
	        Thread.sleep(1000L);
	    } catch (InterruptedException e) {
	        throw new RuntimeException(e);
	    }
	}
}

在这里插入图片描述在这里插入图片描述
用CompletableFuture 实现异步

在这里插入图片描述异常处理

public Future<Double> getPriceAsync(String product) {
    return CompletableFuture.supplyAsync(() -> calculatePrice(product));
}

用CompletableFuture实现

List<Shop> shops = Arrays.asList(new Shop("BestPrice"),
                                 new Shop("LetsSaveBig"),
                                 new Shop("MyFavoriteShop"),
                                 new Shop("BuyItAll"));
                                 
public List<String> findPrices(String product) {
    return shops.stream()
       .map(shop -> String.format("%s price is %.2f",
                                  shop.getName(), shop.getPrice(product)))
       .collect(toList());
}
//测试性能
long start = System.nanoTime();
System.out.println(findPrices("myPhone27S"));
long duration = (System.nanoTime() - start) / 1_000_000;
System.out.println("Done in " + duration + " msecs");

多个有阻塞(这里模拟的外部服务调用)的方法同时被调用,性能可能出现瓶颈。

List<CompletableFuture<String>> priceFutures =
        shops.stream()
        .map(shop -> CompletableFuture.supplyAsync(
             () -> String.format("%s price is %.2f",
             shop.getName(), shop.getPrice(product))))
        .collect(toList());

异步化

在这里插入图片描述完整的异步化

在这里插入图片描述图解

在这里插入图片描述设置Executor里的线程数,根据公式:Nthreads = CPU数 * CPU利用率 * (1 + 等待时间/计算时间)

CompletableFuture.supplyAsync(() -> shop.getName() + " price is " +                                    shop.getPrice(product), executor);

指定Executor

public class Discount {
    public enum Code {
        NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20);

        private final int percentage;

        Code(int percentage) {
            this.percentage = percentage;
        }
    }
    // Discount class implementation omitted, see Listing 11.14
}

public String getPrice(String product) {
    double price = calculatePrice(product);
    Discount.Code code = Discount.Code.values()[
                            random.nextInt(Discount.Code.values().length)];
    return String.format("%s:%.2f:%s", name, price, code);
}
private double calculatePrice(String product) {
    delay();
    return random.nextDouble() * product.charAt(0) + product.charAt(1);
}

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; }}

添加会员打折

在这里插入图片描述假设打折也需要调用远程服务,也会有延迟。

在这里插入图片描述
同步的实现方式,也就是顺序执行

在这里插入图片描述链接两个异步调用
在这里插入图片描述图示

在这里插入图片描述
连接独立的两个异步调用
在这里插入图片描述图示

在这里插入图片描述Java7 里,两个独立的异步调用连接的实现

private static final Random random = new Random();
public static void randomDelay() {
    int delay = 500 + random.nextInt(2000);
    try {
        Thread.sleep(delay);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}

对不同服务的调用,相应时间应该是不同的。

public Stream<CompletableFuture<String>> findPricesStream(String product) {
    return shops.stream()
             .map(shop -> CompletableFuture.supplyAsync(
                                   () -> shop.getPrice(product), executor))
             .map(future -> future.thenApply(Quote::parse))
             .map(future -> future.thenCompose(quote ->
                      CompletableFuture.supplyAsync(
                          () -> Discount.applyDiscount(quote), executor)));
}

直接返回Stream

CompletableFuture[] futures = findPricesStream("myPhone") 
       .map(f -> f.thenAccept(System.out::println)).toArray(size -> new CompletableFuture[size]);
CompletableFuture.allOf(futures).join();
long start = System.nanoTime();
CompletableFuture[] futures = findPricesStream("myPhone27S")
        .map(f -> f.thenAccept(
             s -> System.out.println(s + " (done in " +
                  ((System.nanoTime() - start) / 1_000_000) + " msecs)")))
        .toArray(size -> new CompletableFuture[size]);
CompletableFuture.allOf(futures).join();
System.out.println("All shops have now responded in "
                   + ((System.nanoTime() - start) / 1_000_000) + " msecs");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值