📝

CompletableFuture の使い方

2022/11/25に公開

CompletableFutureとは

CompletableFuture は Future と CompletionStage を実装したクラスです。
非同期にタスクを処理することができ、いくつかの CompletableFuture を並列に処理するか、マージして処理することができます。

https://docs.oracle.com/javase/jp/8/docs/api/java/util/concurrent/CompletableFuture.html

CompletableFutureの使い方

CompletableFutureの結果取得

get()

Futureインタフェースのメソッド
get() でCompletableFutureが完了するのを待機して結果を取得します。
また、タイムアウト値を設定することができる

join()

CompletableFuture クラスのメソッド
get() と同じで CompletableFuture が完了するのを待機して結果を取得します。

CompletableFutureの生成

runAsync()

非同期実行するオブジェクト(T=Void)を生成します

@Test
fun test() {
  val future = CompletableFuture.runAsync { println("future example") }
  println("get(): " + future.get());
}
// future example
// get(): null

supplyAsync()

Supplier<U>を非同期実行し、完了している CompletableFuture<U>を生成します

@Test
fun test() {
  val future = CompletableFuture.supplyAsync {
    println("Start")
    // 重たい処理
    "end"
  }
  println("get(): " + future.get())
}
// Starting
// get(): end

completedFuture()

<U>型の引数をもらって、完了している CompletableFuture<U> を生成します

@Test
fun test() {
  val completableFuture = CompletableFuture.completedFuture("test!")

  val result = completableFuture.get()
  println(result)
  // test!
}

CompletableFutureの後処理

thenApply()

CompletableFuture の処理のあと戻り値があるタスクを実行する

@Test
fun test() {
  val future = CompletableFuture
    .supplyAsync { "Hello" }
    .thenApply { "$it World" }

  println("future.get(): " + future.get())
  // future.get(): Hello World
}

thenAccept()

CompletableFuture の処理のあと戻り値がないタスクを実行する

@Test
fun test() {
  val future1 = CompletableFuture.supplyAsync { "Hello" }

  val future2 = future1.thenAccept { println("$it World") }
  println("future1.get(): " + future1.get())
  println("future2.get(): " + future2.get())
  // Hello World
  // future1.get(): Hello
  // future2.get(): null
}

thenRun()

CompletableFutureの合成

thenCompose()

複数の CompletableFuture を直列で実行するように定義することができる

@Test
fun test() {
    val future = CompletableFuture.supplyAsync { "Hello" }
        .thenCompose { CompletableFuture.supplyAsync { "$it World" } }
        .thenCompose { CompletableFuture.supplyAsync { "$it !!!!!!!!" }
        }
    println(future.get())
    // Hello World !!!!!!!!
}

thenCombine()

複数の CompletableFuture を並列で実行するように定義することができる

@Test
fun thenCombineTest() {
    val future1 = CompletableFuture.supplyAsync { "Hello" }
    val future2= CompletableFuture.supplyAsync { "World" }
    val result = future1.thenCombine(future2){f1, f2 ->
        println("f1 :$f1, f2 :$f2")
        return@thenCombine f1 + f2
    }
    
    println("result : ${result.get()}")
    // f1 :Hello, f2 :World
    // result : HelloWorld
}

allOf()

全てのオブジェクト完了後に完了するオブジェクト(Void)を返す

anyOf()

いずれか1つのオブジェクト完了後に完了するオブジェクト(Object)を返す

Discussion