Kotlin协程实战:实现高效轻量的并发编程
协程与传统线程的本质区别
在现代应用开发中,处理并发任务时选择合适的机制至关重要。传统的 Java 线程由操作系统直接管理,每个线程通常占用约 1MB 栈内存,创建成本高且难以大规模使用。
而 Kotlin 协程采用用户态调度,仅需几 KB 内存即可创建,支持百万级并发任务而不引发内存溢出。
// 传统线程方式(容易崩溃)
for (i in 0 until 10_000) {
Thread { performTask() }.start()
}
// 协程方式(流畅运行)
repeat(100_000) {
GlobalScope.launch { performTask() }
}
快速入门:构建首个协程
通过 runBlocking 启动一个协程,它会阻塞当前线程直到内部协程完成。
fun main() = runBlocking {
launch {
delay(1_000) // 非阻塞等待
println("World!")
}
println("Hello,")
}
// 输出顺序:
// Hello,
// (1秒后)World!
作用域管理:控制协程生命周期
协程的作用域决定了其生命周期和执行上下文:
- GlobalScope:全局作用域,不受控,适合短时任务
- runBlocking:阻塞调用方线程,直到协程结束
- coroutineScope:挂起当前协程,等待所有子协程完成
- viewModelScope(Android):绑定到 ViewModel,自动清理
suspend fun fetchUserData() = coroutineScope {
val userJob = async { fetchUserInfo() }
val orderJob = async { fetchUserOrders() }
Pair(userJob.await(), orderJob.await())
}
挂起函数:异步操作的同步写法
使用 suspend 修饰符定义的函数可在协程中暂停执行,但不会阻塞底层线程。
suspend fun retrieveProfile(): UserProfile {
return withContext(Dispatchers.IO) {
networkClient.get("/profile")
}
}
fun loadProfile() = viewModelScope.launch {
showProgress()
val profile = retrieveProfile() // 暂停等待结果
updateDisplay(profile)
hideProgress()
}
调度器:精准分配执行环境
不同场景应使用不同的调度策略:
Dispatchers.Main:用于 UI 更新Dispatchers.IO:处理 I/O 操作(网络、文件)Dispatchers.Default:执行计算密集型任务- 自定义线程池:如固定大小的线程池
val customPool = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
withContext(customPool) {
processLargeData()
}
异常处理机制
协程支持全局与局部异常捕获,提升程序健壮性。
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
logError(throwable)
}
val job = GlobalScope.launch(exceptionHandler) {
throw IllegalStateException("Something went wrong")
}
// 局部异常处理
try {
val result = async { riskyOperation() }.await()
} catch (e: Exception) {
handleFailure(e)
}
实战案例:并行加载多源数据
利用 async 与 await 可轻松实现多个请求并行执行。
suspend fun loadAllData(userId: Int): UserDataResult {
return coroutineScope {
val userInfo = async { fetchUser(userId) }
val recentOrders = async { fetchRecentOrders(userId) }
val preferences = async { fetchPreferences(userId) }
UserDataResult(
user = userInfo.await(),
orders = recentOrders.await(),
prefs = preferences.await()
)
}
}
相比 Java 的 CompletableFuture,Kotlin 协程以更直观的结构化方式表达异步逻辑,避免回调嵌套。
核心优势总结
- 极低开销:可轻松创建数十万并发任务
- 结构化并发:作用域自动管理协程生命周期
- 非阻塞挂起:用同步风格编写异步代码
- 灵活调度:按任务类型分配执行线程