検証環境
この記事の内容は、以下の環境で検証しました。
- Intellij IDEA ULTIMATE 2018.2
- Kotlin 1.3.0
- Gradle Projectで作成
- GradleファイルはKotlinで記述(KotlinでDSL)
準備
詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa
Scope builder
このブロックのタイトルは「Scope builder」となっています。
なんとなくですが、スコープを作れるのではと勘ぐってしまうタイトルです。
それでは、読み進めていきます。
In addition to the coroutine scope provided by different builders, it is possible to declare your own scope using coroutineScope builder.
It creates new coroutine scope and does not complete until all launched children complete.
The main difference between runBlocking and coroutineScope is that the latter does not block the current thread while waiting for all children to complete.
意訳込みですが翻訳すると以下のようなります。
異なるスコープのビルダーに加えて、 coroutineScope を使用すれば、独自のスコープも定義できます。
coroutineScope で新しく定義したコルーチンは、起動したすべての子コルーチンが完了するまで、終わりません。
runBlocking と coroutineScope との違いがあります。 runBlocking は起動した子コルーチンが完了するまで処理をまちます。 coroutineScope は子コルーチンの完了をまちません。
なるほど、上記の説明を読むとサンプルコードと実行結果がなっとくできます。
公式サイトのサンプルコードは以下のようなっています。
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(200L)
println("Task from runBlocking")
}
coroutineScope { // Creates a new coroutine scope
launch {
delay(500L)
println("Task from nested launch")
}
delay(100L)
println("Task from coroutine scope") // This line will be printed before nested launch
}
println("Coroutine scope is over") // This line is not printed until nested launch completes
}
結果が以下のとおりです。
Task from launch-launch
Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over
runBlockingは子コルーチンが終わるまで待っているから、「Coroutine scope is over」の出力が一番最後なんですね。
これらの説明を図にするとこんな感じです。
ということは、coroutineScopeだけでコルーチンを実装していくと、どこかでjoinしない限りは子コルーチンの完了を待ちません。
結果的にrunBlockingを使う事が望ましいわけですね。
まとめ
このブロックで理解できたことは以下のことだと思います。
- coroutineScopeで独自のスコープを定義できる
- coroutineScopeは子コルーチンの完了をまたない
- runBlockingは子コルーチンの完了を待つ