2017-02-28 86 views
8

我是新的Java 8併發特性,如CompletableFuture,我希望你能幫助上手以下使用情況。的Java 8 - 呼叫方法異步並行,並結合他們的結果

有一個名爲TimeConsumingServices服務,提供耗時的操作,我想以並行方式運行,因爲它們都是獨立於。

interface TimeConsumingService { 

    default String hello(String name) { 
    System.out.println(System.currentTimeMillis() + " > hello " + name); 
    return "Hello " + name; 
    } 
    default String planet(String name) { 
    System.out.println(System.currentTimeMillis() + " > planet " + name); 
    return "Planet: " + name; 
    } 
    default String echo(String name) { 
    System.out.println(System.currentTimeMillis() + " > echo " + name); 
    return name; 
    } 

    default byte[] convert(String hello, String planet, String echo) { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(hello); 
    sb.append(planet); 
    sb.append(echo); 
    return sb.toString().getBytes(); 
    } 
} 

到目前爲止,我實現了以下示例,並且我設法並行調用了所有三種服務方法。

public class Runner implements TimeConsumingService { 

    public static void main(String[] args) { 
    new Runner().doStuffAsync(); 
    } 

    public void doStuffAsync() { 
    CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> this.hello("Friend")); 
    CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> this.planet("Earth")); 
    CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> this.echo("Where is my echo?")); 

    CompletableFuture.allOf(future1, future2, future3).join(); 
    } 
} 

有沒有辦法收集每個服務調用的返回值和調用方法byte[]‘ convert(String, String, String)

回答

8

要合併的結果你已經返回他們畢竟,你可以做這樣的事情

CompletableFuture<byte[]> byteFuture = CompletableFuture.allOf(cf1, cf2, cf3) 
        .thenApplyAsync(aVoid -> convert(cf1.join(), cf2.join(), cf3.join())); 
byte[] bytes = byteFuture.join(); 

這將運行所有的期貨,等待他們都只要他們都完成了將打電話給你的完成,然後你提到的方法。

2

後加入,你可以簡單地從future1get()值:

String s1 = future1.get() 

+0

但如果我叫'future1.get(); future2.get(); future3.get();'它們不是並行調用的,不是嗎? – saw303

+2

當你調用future1.get(),那麼你只得到已經計算的結果。 –

+1

是取得成果是不是在並行調用,但是所有的方法將被異步計算。你可以通過添加'TimeUnit.seconds(2).sleep()'來檢查它。加入方法後。你會看到'System.out.println'在睡眠之前被調用。 – user2377971

0

您可以使用這些方法thenCombine()如果只有3期貨完成合並:

final CompletableFuture<byte[]> byteFuture = future1.thenCombine(future2, (t, u) -> { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(t); 
    sb.append(u); 
    return sb.toString(); 
}).thenCombine(future3, (t, u) -> { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(t); 
    sb.append(u); 
    return sb.toString(); 
}).thenApply(s -> s.getBytes()); 

try { 
    final byte[] get = byteFuture.get(); 
} catch (InterruptedException | ExecutionException ex) { 
}