Kotlinのsuspend関数とは?
〜非同期処理をシンプルに書くための魔法のキーワード〜
概要(Overview)
suspend は 「中断可能な関数」 を意味します。
Kotlinでは、非同期処理や長時間かかる処理を安全に実行するために、
コルーチン(Coroutine) を使いますが、suspend はそのコルーチンの“要”となるキーワードです。
suspend fun fetchUser(): User {
delay(1000) // 一時中断(スレッドはブロックされない)
return User("Anna")
}
この関数は delay() を呼んで1秒「中断」しますが、
スレッドはブロックされません。
そのため、同じスレッド上で他のコルーチンが並行実行できます。
なぜsuspendが必要なの?
通常の関数は、呼び出しが終わるまでスレッドを専有します。
しかし、I/O処理やネットワーク通信などは時間がかかるため、スレッドをブロックしてしまうのは非効率です。
suspend関数を使えば、
「一時中断 → 再開」という形でスレッドをブロックせずに処理を続けられるようになります。
suspend関数のポイントまとめ
| 項目 | 説明 |
|---|---|
| 意味 | 中断可能な関数 |
| 呼び出し元 | 他のsuspend関数、またはCoroutineScope内 |
| スレッド | ブロックしない(軽量) |
| 使用場面 | ネットワーク通信、DBアクセス、I/O、長時間処理など |
| 戻り値 | 普通の関数と同じ。中断可能なだけで特別ではない |
使用例① — 普通の非同期処理と比較
従来のスレッド方式
fun main() {
Thread {
Thread.sleep(1000)
println("Done!")
}.start()
}
スレッドを生成し、sleepでブロック。
コルーチン方式
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000)
println("Done!")
}
}
delay()はsuspend関数なのでスレッドをブロックせず中断可能。
使用例② — suspend関数を定義して呼び出す
suspend fun fetchData(): String {
delay(500)
return "Data loaded"
}
fun main() = runBlocking {
val result = fetchData()
println(result)
}
ここでポイントは:
-
fetchDataはsuspend関数 -
runBlockingがコルーチンコンテキストを作成 -
fetchData()を安全に呼び出せる
suspend関数同士の呼び出し
suspend関数は他のsuspend関数からのみ呼び出せます。
普通の関数から呼ぶとエラーになります。
suspend fun taskA() { delay(100) }
suspend fun taskB() { taskA() } // OK
fun main() {
taskA() // ❌ エラー: suspend関数は通常関数から呼べない
}
呼び出すには runBlocking か launch / async などのコルーチンスコープが必要です。
suspend関数は「中断点」を持つだけの普通の関数
suspend関数は特別な戻り値型を持っているわけではありません。
ただ、コンパイラが「中断点(suspension point)」を追跡できるようにするためのマークです。
実際、suspend関数は内部的に「状態マシン」に変換されます。
つまり:
suspend funは「中断できる可能性を持つ普通の関数」なのです。
応用:withContextを使ったスレッド切り替え
suspend関数内では、別スレッドで処理を行いたいときに withContext が使えます。
suspend fun readFile(): String = withContext(Dispatchers.IO) {
File("data.txt").readText()
}
Dispatchers.IO はI/O処理専用のスレッドプールを使う
suspend関数内で安全にスレッドを切り替え可能
まとめ
| 概念 | 説明 |
|---|---|
suspend |
中断可能な関数を定義するための修飾子 |
| 利点 | スレッドをブロックせずに非同期処理を記述できる |
| 注意点 | 通常関数から直接呼べない(コルーチンスコープが必要) |
| よく使う関数 |
delay(), withContext(), await(), yield() など |