web-dev-qa-db-ja.com

Java 8-非同期でメソッドを呼び出し、結果を結合する

私はJava CompletableFutureなどの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();
  }
}
_

これまでに次の例を実装し、3つのサービスメソッドすべてを並行して呼び出すことができました。

_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)を呼び出す方法はありますか?

11
saw303

あなたがそれらを返した後に結果を組み合わせるために、あなたはこのようなことをすることができます

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

これにより、すべてのフューチャーが実行され、すべてが完了するのを待ちます。その後、フューチャーがすべて完了するとすぐに、あなたが言及したconvertメソッドが呼び出されます。

12
Ash

結合後は、次のように_future1_からget()値を単純に取得できます。

_String s1 = future1.get()
_

等々

4
user2377971

完了する先物が3つしかない場合は、thenCombine()メソッドを使用してそれらを組み合わせることができます。

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) {
}
1
MBec