Kotlin 协程基础 #
一、协程概述 #
协程是一种轻量级的线程,可以挂起和恢复执行,而不阻塞线程。
1.1 协程 vs 线程 #
| 特性 | 协程 | 线程 |
|---|---|---|
| 创建成本 | 极低 | 较高 |
| 内存占用 | 几KB | 几MB |
| 切换成本 | 低 | 高 |
| 数量限制 | 可创建大量 | 受限 |
1.2 协程优势 #
- 轻量级:可以创建成千上万个协程
- 简洁:用同步代码写异步逻辑
- 安全:结构化并发,避免泄漏
二、添加依赖 #
kotlin
// build.gradle.kts
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
// Android 需要添加
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
}
三、第一个协程 #
3.1 launch #
kotlin
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000)
println("World!")
}
println("Hello")
}
// 输出:
// Hello
// World!
3.2 runBlocking #
kotlin
fun main() = runBlocking {
println("Start")
delay(1000)
println("End")
}
3.3 GlobalScope #
kotlin
fun main() = runBlocking {
GlobalScope.launch {
delay(1000)
println("Global coroutine")
}
delay(2000) // 等待全局协程完成
}
四、suspend 函数 #
4.1 定义 suspend 函数 #
kotlin
suspend fun fetchData(): String {
delay(1000) // 模拟网络请求
return "Data from server"
}
fun main() = runBlocking {
val data = fetchData()
println(data)
}
4.2 suspend 函数特点 #
- 只能在协程或其他 suspend 函数中调用
- 可以挂起协程而不阻塞线程
- 挂起后可以恢复执行
4.3 常用 suspend 函数 #
kotlin
// delay:延迟
delay(1000)
// withContext:切换上下文
withContext(Dispatchers.IO) {
// IO 操作
}
// await:等待 Deferred 结果
val result = async { compute() }.await()
五、协程构建器 #
5.1 launch #
启动新协程,不返回结果:
kotlin
fun main() = runBlocking {
launch {
println("Task 1")
}
launch {
println("Task 2")
}
}
5.2 async #
启动新协程,返回 Deferred:
kotlin
fun main() = runBlocking {
val deferred = async {
delay(1000)
"Result"
}
println("Waiting...")
val result = deferred.await()
println(result)
}
5.3 并行执行 #
kotlin
suspend fun task1(): Int {
delay(1000)
return 1
}
suspend fun task2(): Int {
delay(1000)
return 2
}
fun main() = runBlocking {
val time = measureTimeMillis {
val a = async { task1() }
val b = async { task2() }
println("Result: ${a.await() + b.await()}")
}
println("Time: $time ms") // 约 1000ms,而非 2000ms
}
六、协程作用域 #
6.1 CoroutineScope #
kotlin
fun main() = runBlocking {
coroutineScope {
launch {
delay(1000)
println("Task 1")
}
launch {
delay(500)
println("Task 2")
}
}
println("All tasks completed")
}
6.2 结构化并发 #
kotlin
fun main() = runBlocking {
coroutineScope {
launch {
delay(1000)
println("Child 1")
}
launch {
delay(500)
println("Child 2")
}
}
// 等待所有子协程完成
println("Parent completed")
}
七、协程上下文 #
7.1 Dispatchers #
kotlin
fun main() = runBlocking {
launch(Dispatchers.Main) {
// 主线程(UI 线程)
}
launch(Dispatchers.IO) {
// IO 线程池(网络、文件操作)
}
launch(Dispatchers.Default) {
// 默认线程池(CPU 密集型)
}
launch(Dispatchers.Unconfined) {
// 不限制线程
}
}
7.2 withContext 切换上下文 #
kotlin
suspend fun loadData(): String {
return withContext(Dispatchers.IO) {
// 在 IO 线程执行
delay(1000)
"Data"
}
}
八、Job #
8.1 获取 Job #
kotlin
fun main() = runBlocking {
val job = launch {
delay(1000)
println("Task completed")
}
job.join() // 等待协程完成
println("After join")
}
8.2 Job 状态 #
kotlin
fun main() = runBlocking {
val job = launch {
delay(1000)
}
println("isActive: ${job.isActive}")
println("isCompleted: ${job.isCompleted}")
println("isCancelled: ${job.isCancelled}")
job.join()
println("isCompleted after join: ${job.isCompleted}")
}
九、实战示例 #
9.1 模拟网络请求 #
kotlin
suspend fun fetchUser(id: Int): User {
return withContext(Dispatchers.IO) {
delay(1000) // 模拟网络延迟
User(id, "User $id")
}
}
suspend fun fetchPosts(userId: Int): List<Post> {
return withContext(Dispatchers.IO) {
delay(500)
listOf(Post(1, "Post 1"), Post(2, "Post 2"))
}
}
fun main() = runBlocking {
val user = fetchUser(1)
println("User: $user")
val posts = fetchPosts(user.id)
println("Posts: $posts")
}
data class User(val id: Int, val name: String)
data class Post(val id: Int, val title: String)
9.2 并行加载 #
kotlin
suspend fun loadAllData(): AllData {
return coroutineScope {
val user = async { fetchUser(1) }
val posts = async { fetchPosts(1) }
val comments = async { fetchComments(1) }
AllData(
user = user.await(),
posts = posts.await(),
comments = comments.await()
)
}
}
十、最佳实践 #
10.1 使用结构化并发 #
kotlin
// 推荐
fun main() = runBlocking {
coroutineScope {
launch { task1() }
launch { task2() }
}
}
// 不推荐
fun main() = runBlocking {
GlobalScope.launch { task1() }
GlobalScope.launch { task2() }
}
10.2 选择合适的 Dispatcher #
kotlin
// IO 操作
withContext(Dispatchers.IO) { }
// CPU 密集型
withContext(Dispatchers.Default) { }
// UI 更新
withContext(Dispatchers.Main) { }
10.3 使用 suspend 函数 #
kotlin
// 推荐
suspend fun loadData(): Data {
return withContext(Dispatchers.IO) {
// ...
}
}
// 不推荐:使用回调
fun loadData(callback: (Data) -> Unit) {
thread {
val data = fetchData()
callback(data)
}
}
十一、总结 #
协程基础要点:
| 概念 | 说明 |
|---|---|
| launch | 启动协程,不返回结果 |
| async | 启动协程,返回 Deferred |
| suspend | 挂起函数关键字 |
| runBlocking | 阻塞当前线程 |
| coroutineScope | 创建协程作用域 |
| Dispatchers | 协程调度器 |
下一步,让我们学习 协程构建器!
最后更新:2026-03-27