Kotlin协程核心库kotlinx-coroutines-core全面解析
2025-07-06 02:58:18作者:郁楠烈Hubert
协程基础概念
Kotlin协程是一种轻量级的线程管理方案,它允许开发者以同步的方式编写异步代码,同时提供了更高效的资源利用方式。与线程相比,协程的创建和切换成本更低,可以轻松创建成千上万个而不会导致系统资源耗尽。
核心协程构建器
1. launch构建器
launch
是最基础的协程构建器,它启动一个不返回结果的协程。适用于"即发即忘"的场景。
scope.launch {
// 执行异步操作
delay(1000)
println("协程执行完成")
}
2. async构建器
async
构建器返回一个Deferred
对象,可以通过await()
获取异步操作的结果。适用于需要获取结果的并行任务。
val deferred = scope.async {
delay(1000)
"计算结果"
}
// 其他操作...
val result = deferred.await()
println(result) // 输出: 计算结果
3. runBlocking构建器
runBlocking
会阻塞当前线程,直到协程执行完成。主要用于测试或main函数中。
fun main() = runBlocking {
launch {
delay(1000)
println("来自协程")
}
println("Hello")
}
// 输出:
// Hello
// 来自协程
协程调度器(Dispatchers)
Kotlin提供了几种预定义的调度器,用于控制协程的执行线程:
- Dispatchers.Main - 在主线程(UI线程)上执行协程,主要用于Android等UI应用
- Dispatchers.Default - 使用共享的后台线程池,适合CPU密集型任务
- Dispatchers.IO - 使用专为IO操作优化的线程池,适合文件或网络IO
- Dispatchers.Unconfined - 不限制协程执行线程,从启动线程开始,在恢复线程继续
scope.launch(Dispatchers.IO) {
// 执行IO操作
val data = fetchDataFromNetwork()
withContext(Dispatchers.Main) {
// 更新UI
updateUI(data)
}
}
协程上下文与作用域
协程上下文(CoroutineContext)包含协程运行的各种元素,如Job、调度器等。CoroutineScope定义了协程的生命周期范围。
val scope = CoroutineScope(Dispatchers.Main + Job())
scope.launch {
// 协程体
}
// 取消scope下的所有协程
scope.cancel()
协程通信与数据流
1. Channel通道
Channel提供了一种在协程间传递数据的方式,类似于阻塞队列。
val channel = Channel<Int>()
scope.launch {
for (x in 1..5) {
channel.send(x * x)
}
channel.close()
}
scope.launch {
for (y in channel) {
println(y)
}
}
// 输出: 1 4 9 16 25
2. Flow流
Flow是Kotlin的响应式流实现,可以按顺序发出多个值。
fun simpleFlow(): Flow<Int> = flow {
for (i in 1..3) {
delay(100)
emit(i)
}
}
scope.launch {
simpleFlow().collect { value ->
println(value)
}
}
// 输出: 1 2 3
协程同步原语
1. Mutex互斥锁
确保同一时间只有一个协程能访问共享资源。
val mutex = Mutex()
var counter = 0
repeat(100) {
scope.launch {
mutex.withLock {
counter++
}
}
}
2. Semaphore信号量
限制同时访问某资源的协程数量。
val semaphore = Semaphore(3) // 允许3个协程同时访问
repeat(10) {
scope.launch {
semaphore.acquire()
try {
delay(1000)
println("执行任务 $it")
} finally {
semaphore.release()
}
}
}
异常处理
协程提供了多种异常处理机制:
val handler = CoroutineExceptionHandler { _, exception ->
println("捕获异常: $exception")
}
scope.launch(handler) {
throw RuntimeException("测试异常")
}
协程取消
协程支持结构化并发,可以方便地取消整个协程树。
val job = scope.launch {
repeat(1000) { i ->
println("job: 我在数 $i")
delay(500)
}
}
delay(2000)
job.cancel() // 取消协程
高级特性
1. select表达式
select
允许同时等待多个挂起函数,并在第一个可用时执行。
val x = select<String> {
async1.onAwait { it }
async2.onAwait { it }
}
2. 超时控制
try {
withTimeout(1300) {
repeat(1000) { i ->
println("我在数 $i")
delay(500)
}
}
} catch (e: TimeoutCancellationException) {
println("超时了")
}
实际应用建议
- 在Android中,使用
viewModelScope
或lifecycleScope
来自动管理协程生命周期 - 避免在协程中使用全局Scope,防止内存泄漏
- 对于网络请求,结合
Retrofit
等库的协程支持 - 数据库操作可以使用
Room
的协程支持 - 复杂的UI动画可以使用协程简化时序控制
Kotlin协程通过简洁的API和强大的功能,极大地简化了异步编程的复杂性,是现代Kotlin开发不可或缺的工具。