コルーチン Coroutin

コルーチン

使うにあたって

dependencyの追加

https://github.com/Kotlin/kotlinx.coroutines#using-in-your-projects

Gradleの場合

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
}

import

App.kt

import kotlinx.coroutines.*

About コルーチン in Kotlin

非同期関数

asyncに相当する関数を生成する。

//  launch内部は非同期で実行される
launch { 
    println("Hello World")
}

生成と実行

コルーチンスコープ内部で生成することが出来る

// コルーチンスコープの生成
runBlocking { // this: CoroutineScope
    // コルーチンの生成 (launchは、CoroutineScopeのメソッド)
    launch { 
    }
}

Job

CoroutineScope.launch()によって生成されるコルーチンはJobとしてその参照を返す。

fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job

カレントスレッドをブロックしないで、新しいコルーチンを起動し、Jobとしてコルーチンの参照を渡す。 このjobがキャンセルされたとき、コルーチンがキャンセルされる。

サスペンド関数

コルーチンの実行を中断する関数await に相当する関数。

suspend修飾子を関数につける。

App.kt

import kotlinx.coroutines.*

// サスペンド関数 (コルーチンを中断する)
suspend fun doWorld() {
    delay(1000L)
    println("World")
}

fun main() {
    runBlocking {
        doWorld() // 完了まで中断する
        println("Hello")
    }
}

/* 出力
World
Hello
*/

コルーチンコンテキスト

インデックスされたElementの集合インスタンスを表す。 コンテキスト同士を結合して新たなコルーチンコンテキストを作ることも出来る

open operator fun plus(
    context: CoroutineContext
): CoroutineContext
(source)
class MyActivity : Activity(), CoroutineScope {

    private val job = Job()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

Job

Elementの一種。 コルーチンへの参照を表すコルーチンコンテキスト。

f:id:yossan2:20210627162655p:plain
Job

CoroutineDispatcher

Elementの一種。 コルーチンを実行するスレッドを表すコルーチンコンテキスト。

f:id:yossan2:20210627162722p:plain
CoroutineDispatcher

CoroutineDispatcherとして用意されている。

  • Dispatchers.Default - タスクは、適切なバックグラウンドスレッドに読み込まれるように設計されたCorountineDispatcher。
  • Dispatchers.IO - IOタスクをブロックするスレッドの共有プールに、予め読み込んでおくために設計されたCorountineDispatcher。
  • Dispatchers.Main - メインスレッド上で動作することが保証されたCorountineDispatcher。
  • Dispatchers.Unconfined

コルーチンスコープ

  • コルーチンコンテキストを持つ
  • コルーチンを起動するメソッドを持つ
    • launc
    • async
    • promise
    • ...

生成方法

両者の違いは、CorountineDispatcherが異なる。

  • CoroutineScope() - Dispatchers.Default
  • MainScope() - Dispatcher.Main

まとめ

  • コルーチンコンテキストはElementの集合を表す
  • Jobは、コルーチンへの参照を表すElementであり、コルーチンコンテキスト
  • CorutinDispatherは、タスクを実行するスレッドを表すElementであり、コルーチンコンテキスト
  • コルーチンスコープはコルーチンコンテキストを持つ