在我们平时写的项目中,异步调用是一个比较重要的优化手段,在 Java 中,提供了 CompletedFuture 供我们使用,具体实现如下:

例子

假如现在有一个需求,我需要去淘宝、天猫和京东去搜索某样商品的价格,哪个平台价格低我就去哪个平台购买。

代码

现在我模拟了三个方法:分别是去淘宝、天猫和京东去搜索价格

  private static double priceOfTb() {
    delay();
    return new Random().nextDouble() * 100 ;
  }

  private static double priceOfTm() {
    delay();
    return new Random().nextDouble() * 100;
  }

  private static double priceOfJd() {
    delay();
    return new Random().nextDouble() * 100;
  }

delay 方法是模拟是搜索价格耗时:

  private static void delay() {
    int time = new Random().nextInt(5);
    SleepHelper.sleep(time);
    System.out.printf("search cost %s seconds\n", time);
  }

如果使用同步的方法,耗时如下:

  public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
    long start;
    start = System.currentTimeMillis();

    double tb = priceOfTb();
    double tm = priceOfTm();
    double jd = priceOfJd();


    System.out.println("淘宝价格:" + tb);
    System.out.println("天猫价格:" + tm);
    System.out.println("京东价格:" + jd);


    System.out.println("cost time " + (System.currentTimeMillis() - start)/1000 + "秒");

  }

使用 CompeletedFuture 实现异步调用-小白菜博客
耗时是 3+3+2 一共耗时 8 秒
如果使用异步的方法,耗时如下:

  public static void main(String[] args) throws ExecutionException, InterruptedException, IOException {
    long start;
    start = System.currentTimeMillis();

    CompletableFuture<Double> tb = CompletableFuture.supplyAsync(CompletedFutureTest::priceOfTb);
    CompletableFuture<Double> tm = CompletableFuture.supplyAsync(CompletedFutureTest::priceOfTm);
    CompletableFuture<Double> jd = CompletableFuture.supplyAsync(CompletedFutureTest::priceOfJd);

    // join 方法是等待 tb,tm,jd 都执行完了才继续往下执行
    CompletableFuture.allOf(tb, tm, jd).join();

    System.out.println("淘宝价格:" + tb.get());
    System.out.println("天猫价格:" + tm.get());
    System.out.println("京东价格:" + jd.get());

    System.out.println("cost time " + (System.currentTimeMillis() - start)/1000 + "秒");

  }

使用 CompeletedFuture 实现异步调用-小白菜博客
一共花费了 3 秒