Kotlin协程并发
外观
Kotlin协程并发[编辑 | 编辑源代码]
介绍[编辑 | 编辑源代码]
Kotlin协程并发是Kotlin协程库中用于实现轻量级并发编程的核心机制。与传统的线程不同,协程通过挂起(suspend)而非阻塞的方式实现并发,显著提高了资源利用率。Kotlin协程的并发模型基于结构化并发(Structured Concurrency),确保任务的生命周期可预测且易于管理。
核心概念[编辑 | 编辑源代码]
- 挂起函数(Suspend Function):标记为`suspend`的函数,可在不阻塞线程的情况下暂停执行。
- 协程作用域(CoroutineScope):定义协程的生命周期范围,如`GlobalScope`或自定义作用域。
- 调度器(Dispatcher):决定协程运行的线程(如`Dispatchers.IO`、`Dispatchers.Default`)。
- 并发原语:如`async`/`await`、`Mutex`等,用于协调并发操作。
基础用法[编辑 | 编辑源代码]
以下是使用`async`并发执行多个任务的示例:
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
fun main() = runBlocking {
val time = measureTimeMillis {
val result1 = async { fetchData1() }
val result2 = async { fetchData2() }
println("Result: ${result1.await() + result2.await()}")
}
println("Time taken: $time ms")
}
suspend fun fetchData1(): Int {
delay(1000)
return 42
}
suspend fun fetchData2(): Int {
delay(1000)
return 58
}
输出:
Result: 100 Time taken: 1012 ms
解释:
- `async`启动两个并发任务,分别调用`fetchData1`和`fetchData2`。
- `await`等待结果并求和,总时间约为1秒(而非2秒),体现并发优势。
高级并发控制[编辑 | 编辑源代码]
使用Mutex避免竞态条件[编辑 | 编辑源代码]
当多个协程访问共享资源时,需使用互斥锁(`Mutex`):
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
val mutex = Mutex()
var counter = 0
fun main() = runBlocking {
repeat(100) {
launch(Dispatchers.Default) {
mutex.withLock {
counter++
}
}
}
delay(500)
println("Counter: $counter") // 正确输出100
}
结构化并发示例[编辑 | 编辑源代码]
通过`coroutineScope`限定子协程生命周期:
fun main() = runBlocking {
val result = coroutineScope {
val deferred1 = async { compute(1) }
val deferred2 = async { compute(2) }
deferred1.await() + deferred2.await()
}
println(result)
}
suspend fun compute(n: Int): Int {
delay(n * 1000L)
return n * 10
}
实际应用场景[编辑 | 编辑源代码]
并发网络请求[编辑 | 编辑源代码]
合并多个API请求结果:
suspend fun fetchUserData() = coroutineScope {
val profile = async { api.getProfile() }
val orders = async { api.getOrders() }
UserData(profile.await(), orders.await())
}
并行数据处理[编辑 | 编辑源代码]
使用`flow`实现并发流处理:
fun processData() = runBlocking {
val dataFlow = flow {
emit(1)
emit(2)
}
dataFlow.buffer().collect { value ->
launch { processValue(value) }
}
}
性能对比[编辑 | 编辑源代码]
数学基础[编辑 | 编辑源代码]
协程并发的时间复杂度(假设`n`个任务,每个耗时`t`):
- 串行:
- 并发:(理想情况下)
常见问题[编辑 | 编辑源代码]
- Q: 协程是否替代线程?
A: 不完全是。协程适用于I/O密集型任务,计算密集型任务仍需线程池。
- Q: 如何选择调度器?
A: 使用`Dispatchers.IO`进行文件/网络操作,`Dispatchers.Default`用于CPU计算。
总结[编辑 | 编辑源代码]
Kotlin协程通过轻量级的并发模型和结构化并发设计,显著简化了异步编程。掌握`async`/`await`、`Mutex`等工具,能够高效处理并发任务,同时避免常见陷阱如竞态条件。