用CompletableFuture異步執行多個service,並獲取service的返回值

巨大的建築,總是由一木一石疊起來的,我們何妨做做這一木一石呢?我時常做些零碎事,就是爲此。
這是對的,但是我沒有說過這句話! —— 魯迅

java8中增加了一個CompletableFuture,這是對Future的補充.
CompletableFutrue,主要是異步執行,目的的加快執行速度,用不同的線程去執行不同的邏輯,到最後再將得到的結果整合起來.
但是我試了各種的CompletableFuture的異步方法,最終都是同步執行.

用CompletableFuture.allof….join 進行異步觸發

假如有多個completableFutrue,用他的allof方法,會異步執行.
以下用代碼舉例:

建立一個執行時間長的service

import java.text.SimpleDateFormat;
import java.util.Date;

public class MyService {

  private Long value;

  public MyService(Long value) {
    this.value = value;
  }

  public Long getValue() {
    try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + " :myValue" + value);
    return value;
  }

}

調用方法

private void streamService() throws Exception{
    Long start = System.currentTimeMillis();
    Long sum = 0L;
    CompletableFuture[] collect = serviceList.stream()
        .map(service -> CompletableFuture.supplyAsync(service::getValue)).toArray(CompletableFuture[]::new);
    CompletableFuture.allOf(collect).join();
    for (CompletableFuture future : collect) {
      Long value = (Long)future.get();
      sum += value;
    }
    System.out.println(sum);
    Long end = System.currentTimeMillis();
    Long time = (end - start)/1000;
    System.out.println("using " + time);
  }
  1. serviceList是剛纔的MyService的List,先將其轉化爲一個CompletableFuture的數組
  2. 用allOf.join執行
  3. 用每一個CompletableFuture的get來獲取service的返回值

注意

直接對service進行 join 或 get,就直接阻塞了,等執行完了,才能運行到下一個service,不管用.
當allof.join之後,再進行get,此時已經執行完了,有值了,再get,速度回很快

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章