Kotlin でコルーチンを作成して実行する

David Mbochi Njonge 2023年1月30日
  1. Kotlin のコルーチン
  2. Kotlin で新しいプロジェクトを作成し、依存関係を追加する
  3. Kotlin でコルーチンを順番に作成して実行する
  4. Kotlin でコルーチンを同時に作成して実行する
  5. まとめ
Kotlin でコルーチンを作成して実行する

このチュートリアルでは、コルーチンを紹介し、Kotlin で async- await() を使用してコルーチンを順次または同時に実行する方法を示します。

Kotlin のコルーチン

コルーチンは、同期プログラミングのみをサポートする他の通常のプロシージャと比較して、非同期プログラミングをサポートすることを除いて、プロシージャと見なすことができます。

非同期プログラミングは、特定の時点でタスクの実行を一時停止し、一時停止されたタスクがいくつかのバックグラウンドタスクの実行を待機するときに、実行を別のタスクに委任できる手法です。これらのバックグラウンドタスクには、データベースからのレコードの読み取り、Web ページのコンテンツのダウンロード、およびアプリケーションからのユーザー要求の処理が含まれます。

同期プログラミングでは、タスクの実行はどの時点でも中断されず、実行が完了するまでスレッドが排他的に使用されます。

コルーチンは、中断されたルーチンのこのインスタンスを表します。スレッドと見なすこともできますが、コルーチンは、異なるスレッドで実行を一時停止および再開できるため、基になるスレッドに依存しません。

このチュートリアルでは、async- await() 関数が正しい順序で実行されるようにすることで、シーケンシャルコルーチンとコンカレントコルーチンを作成する方法を学習します。

Kotlin で新しいプロジェクトを作成し、依存関係を追加する

IntelliJ に移動し、ファイル>新規>プロジェクトを選択します。開いたウィンドウで、プロジェクト名として kotlinCoroutines と入力し、言語セクションで Kotlin を選択し、ビルドシステムセクションで Gradle を選択して、作成ボタンを押します。

Kotlin でコルーチンを操作するには、コルーチンの依存関係をアプリケーションに追加する必要があります。ファイル build.gradle.kts に移動し、次の依存関係があることを確認します。

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.2")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.2")
    testImplementation(kotlin("test"))
}

依存関係をダウンロードするためのアクティブなインターネット接続があることを確認してください。依存関係がダウンロードされたら、Gradle の変更をロードして、次の手順に進みます。

Kotlin でコルーチンを順番に作成して実行する

アプリケーションの基本パッケージとなる kotlin フォルダーの下にパッケージ com/coroutine を作成します。coroutine フォルダーの下に Main.kt ファイルを作成し、次のコードをコピーしてファイルに貼り付けます。

package com.coroutine

import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking

suspend fun executeProcedureOne(): Int{
    delay(3000L)
    println("procedure one executed")
    return 50;
}

suspend fun executeProcedureTwo(): Int{
    delay(1000L)
    println("procedure two executed")
    return 30;
}

fun main(): Unit = runBlocking {
    val value = async {
        executeProcedureOne()
    }
    value.await()
    val secondValue = async {
        executeProcedureTwo()
    }
    secondValue.await()
}

上記のコードでは、いくつかのバックグラウンドタスクを実行するために一時停止できる executeProcedureOne()executeProcedureTwo() の 2つのメソッドを定義しました。これは、上記のように、suspend キーワードを使用して実現されます。

これらの 2つのメソッドは、基になるスレッドをブロックせずに一時停止できることに注意してください。

main 関数を runBlocking という名前の関数に割り当てました。runBlocking 関数は、メインスレッドで実行され、関数内のコルーチンの実行が完了するまでブロックされるコルーチンを作成するビルダー関数です。

runBlocking 関数内に、それぞれ executeProcedureOne() および executeProcedureTwo() メソッドを呼び出す 2つの async 関数を作成しました。

async 関数は、新しいコルーチンを作成し、Deferred を返すコルーチンビルダーです。Deferred は値を返す約束を表す future であり、await() を使用して値を取得できます。

async の直後に await() を呼び出すと、内部コルーチンが実行されているため、コルーチンが一時停止され、終了すると再開されることに注意してください。

上記のコードは、すべての async 関数が完了するまでコルーチンを強制的に中断し、他のコルーチンに移動できるようになった後、await() メソッドとして順番に実行されます。

上記のコードを実行し、executeProcedureOne() が最も長く遅延した場合でも、executeProcedureTwo() の前に完了することに注意してください。出力は以下のようになります。

procedure one executed
procedure two executed

Kotlin でコルーチンを同時に作成して実行する

前のコードにコメントを付け、次のコードをコピーして、コメントの直後の Main.kt ファイルに貼り付けます。

suspend fun executeProcedureOne(): Int{
    delay(3000L)
    println("procedure one executed")
    return 50;
}

suspend fun executeProcedureTwo(): Int{
    delay(1000L)
    println("procedure two executed")
    return 30;
}

suspend fun executeProcedures() = coroutineScope{
    val firstValue = async {
        executeProcedureOne()
    }

    val secondValue = async {
        executeProcedureTwo()
    }

    firstValue.await()
    secondValue.await()
}

fun main(): Unit = runBlocking  {
    executeProcedures()
}

コルーチンのサスペンドを防ぐために、関数の実行後に async コルーチンビルダーを coroutineScopeawait() を持つ別のサスペンド可能な関数に移動することにより、前の例を並行するように変更しました。

coroutineScoperunBlocking の違いは、coroutineScope が一時停止され、基になるスレッドを解放して他のタスクの実行を継続することです。

上記のコードを実行し、executeProcedureOne() メソッドよりも遅延が少ないため、executeProcedureTwo() メソッドが最初に実行されることに注意してください。出力を以下に示します。

procedure two executed
procedure one executed

まとめ

このチュートリアルでは、コルーチンとは何か、および async- await() 関数を使用してコルーチンを順次または同時に実行する方法を学習しました。また、非同期プログラミング、同期プログラミング、runBlocking{} 関数、coroutineScope{} 関数など、コルーチンのコンテキストでいくつかの一般的な概念を学びました。

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub

関連記事 - Kotlin Coroutine