Kotlin 中唯一让函数成为“可挂起”的修饰符。标记后,函数可以在协程内暂停执行而不阻塞线程。
suspend fun 名称()• 必须使用 suspend 关键字
• 可以在挂起函数中调用其他挂起函数
• 不能从普通函数直接调用(需协程作用域)
suspend fun fetchUser(): User {
return withContext(Dispatchers.IO) {
api.getUser() // 模拟网络
}
}
| 调用场景 | 示例 | 说明 |
|---|---|---|
| 🌱 协程构建器 | launch { fetchUser() } | 最常用,在协程体内直接调用 |
| 🔁 另一个挂起函数 | suspend fun process() { fetchUser() } | 挂起函数可以自由调用其他挂起函数 |
| ⚡ suspend lambda | suspend { fetchUser() } | 通过 suspend 修饰的 lambda 表达式 |
| 🚫 普通函数 | fun main() { fetchUser() } ❌ | 编译错误,必须提供协程环境 |
挂起 ≠ 阻塞
挂起 = 让出线程 + 保存状态
恢复 = 还原状态 + 继续执行
// 定义挂起函数 —— 模拟耗时
// 使用 delay 挂起但不阻塞线程
suspend fun greetAfterDelay(name: String): String {
delay(1000L) // ⏳ 挂起点
return "你好, $name!"
}
// 在 Compose / ViewModel 中调用
fun launchGreeting(scope: CoroutineScope) {
scope.launch {
val result = greetAfterDelay("小智") // 挂起 ~1s
println(result) // 恢复后打印
}
}
| 对比 | 挂起 (suspend) | 阻塞 (blocking) |
|---|---|---|
| 线程 | 释放线程,可被其他协程使用 | 线程一直占用,不能做其他事 |
| 资源 | 高效,支持高并发 | 浪费,线程数有限 |
| 语法 | suspend 关键字 + 协程 | Thread.sleep() / 锁 |
| Compose 中 | ✅ 推荐,不卡UI | ❌ 会导致ANR |