Kotlinの非同期処理とコルーチンの基本を完全解説【Kotlin入門⑫】

非同期処理とは?

プログラムは通常、上から順に命令を実行します。しかし、ネットワーク通信やファイル読み書きなどの処理には時間がかかるため、それらが終わるのを待っているとアプリケーションの応答性が低下します。そこで、非同期処理を活用することで、時間のかかる処理をバックグラウンドで実行し、メインスレッドの動作を止めないようにできます。

Kotlinでは、非同期処理を簡潔に記述できる コルーチン(Coroutines) が用意されています。

コルーチンとは?

コルーチンは、Kotlinの標準ライブラリが提供する軽量な非同期処理の仕組みです。従来のスレッドベースの処理と比べて、より効率的に並行処理を行うことができます。

コルーチンの特徴

  • 軽量: スレッドのようにOSレベルで管理されないため、何千ものコルーチンを同時に実行可能。
  • 簡潔な記述: suspend 関数を使うことで、複雑なコールバック処理を避けられる。
  • キャンセル可能: 実行中のコルーチンを安全にキャンセルできる。
  • 非同期処理を直感的に記述: asynclaunch を使って簡単に非同期処理を記述可能。

コルーチンの基本

Kotlinのコルーチンを使うには、kotlinx.coroutines ライブラリが必要です。

コルーチンのセットアップ

プロジェクトの build.gradle.kts に以下の依存関係を追加します。

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
}

launch を使った基本的なコルーチン

launch は、新しいコルーチンを開始し、非同期に処理を実行します。

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000L) // 1秒待機
        println("Hello, Coroutine!")
    }
    println("処理開始")
}

実行結果:

処理開始
Hello, Coroutine!

async を使った並列処理

async を使うと、複数の非同期処理を並列実行し、結果を取得できます。

import kotlinx.coroutines.*

fun main() = runBlocking {
    val result1 = async { computeValue(10) }
    val result2 = async { computeValue(20) }
    println("結果: ${result1.await() + result2.await()}")
}

suspend fun computeValue(x: Int): Int {
    delay(1000L)
    return x * 2
}

実行結果:

結果: 60

suspend 関数とは?

suspend 関数は、コルーチンの中でのみ実行可能な関数で、非同期処理を簡潔に記述できます。

suspend fun fetchData(): String {
    delay(2000L) // 2秒待機
    return "データ取得完了"
}

fun main() = runBlocking {
    println("データ取得開始")
    val data = fetchData()
    println(data)
}

withContext を使ったスレッド制御

withContext を使うことで、特定のディスパッチャ(スレッド)上で処理を実行できます。

import kotlinx.coroutines.*

fun main() = runBlocking {
    val result = withContext(Dispatchers.IO) {
        fetchData()
    }
    println(result)
}

コルーチンのキャンセル

コルーチンは cancel() メソッドを使ってキャンセルできます。

fun main() = runBlocking {
    val job = launch {
        repeat(1000) { i ->
            println("処理中: $i")
            delay(500L)
        }
    }
    delay(2000L) // 2秒後にキャンセル
    job.cancel()
    println("コルーチンがキャンセルされました")
}

supervisorScope を使ったエラーハンドリング

コルーチンのエラーを安全に処理するには supervisorScope を使用します。

import kotlinx.coroutines.*

fun main() = runBlocking {
    supervisorScope {
        launch {
            throw RuntimeException("エラー発生!")
        }
        launch {
            delay(1000L)
            println("この処理は継続される")
        }
    }
}

まとめ

本記事では、Kotlinの非同期処理とコルーチンの基本について解説しました。

  • コルーチンは軽量で効率的な非同期処理を提供
  • launchasync を使って並列処理を簡潔に記述可能
  • suspend 関数を活用することで非同期処理が直感的に書ける
  • withContext でスレッド制御が可能
  • キャンセルやエラーハンドリングも柔軟に対応可能

コルーチンを活用することで、Kotlinの開発をより快適に進めることができます。