1. 程式人生 > 其它 >使用 CompeletedFuture 實現非同步呼叫

使用 CompeletedFuture 實現非同步呼叫

在我們平時寫的專案中,非同步呼叫是一個比較重要的優化手段,在 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 = priceOfTb();
    double jd = priceOfTb();


    System.out.println("淘寶價格:" + tb);
    System.out.println("天貓價格:" + tm);
    System.out.println("京東價格:" + jd);


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

  }


耗時是 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 + "秒");

  }


一共花費了 3 秒