LoginSignup
2
1

More than 3 years have passed since last update.

Kotlin 1.3のCoroutineのコンテキストとディスパッチャ⑤(親の責任 )

Posted at

検証環境

この記事の内容は、以下の環境で検証しました。

  • Intellij IDEA ULTIMATE 2018.2
  • Kotlin 1.3.0
  • Gradle Projectで作成
  • GradleファイルはKotlinで記述(KotlinでDSL)

準備

詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa

Parental responsibilities

前回に引き続き、公式サイトを読み解いていきます。

今回のタイトルは教育論でしょうかといった具合になっていますが、これまでの流れだと子コルーチンと親コルーチンの話の続きな気がします。

今回は短めです。
早速読み進めてみます。

A parent coroutine always waits for completion of all its children. Parent does not have to explicitly track all the children it launches and it does not have to use Job.join to wait for them at the end:

訳します。

親コルーチンは常に、子コルーチンがすべて完了するまで待ちます。このため、親コルーチンはすべての子コルーチンをまつためにjoinメソッドを明示的に呼び出す必要はありません。

なるほど、言いたいことは親コルーチンは常に子コルーチンが終了するまで待つってことですね。

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    // launch a coroutine to process some kind of incoming request
    val request = launch {
        repeat(3) { i -> // launch a few children jobs
            launch  {
                delay((i + 1) * 200L) // variable delay 200ms, 400ms, 600ms
                println("Coroutine $i is done")
            }
        }
        println("request: I'm done and I don't explicitly join my children that are still active")
    }
    request.join() // wait for completion of the request, including all its children
    println("Now processing of the request is complete")
}

今回は、リピートで3つの子コルーチンを起動しています。
実行結果を確認してみます。

request: I'm done and I don't explicitly join my children that are still active
Coroutine 0 is done
Coroutine 1 is done
Coroutine 2 is done
Now processing of the request is complete

実行結果から、子コルーチンが終わるまで待っているのは理解出来ます。
だけど、説明では、常に待っているからjoinは不要とあったので、コードからjoinを削除してます。
修正後のサンプルコードは以下です。

package step05

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
    // launch a coroutine to process some kind of incoming request
    val request = launch {
        repeat(3) { i -> // launch a few children jobs
            launch  {
                delay((i + 1) * 200L) // variable delay 200ms, 400ms, 600ms
                println("Coroutine $i is done")
            }
        }
        println("request: I'm done and I don't explicitly join my children that are still active")
    }
    println("Now processing of the request is complete")
}

joinメソッドを削除してみました。
実行結果も確認してみます。

Now processing of the request is complete
request: I'm done and I don't explicitly join my children that are still active
Coroutine 0 is done
Coroutine 1 is done
Coroutine 2 is done

joinメソッドを削除することにより、main関数の最後の表示を先に出力します。
しかし、子コルーチンが終わるまでプロセスが終了していないことがわかります。

まとめ

このブロックで理解できたことは以下のことだと思います。

  • 子コルーチンが終了するまで、親コルーチンは終わらないこと
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1