跳转到内容

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) }
    }
}

性能对比[编辑 | 编辑源代码]

pie title 并发模型资源占用对比 "线程" : 85 "协程" : 15

数学基础[编辑 | 编辑源代码]

协程并发的时间复杂度(假设`n`个任务,每个耗时`t`):

  • 串行:O(n×t)
  • 并发:O(t)(理想情况下)

常见问题[编辑 | 编辑源代码]

  • Q: 协程是否替代线程?
 A: 不完全是。协程适用于I/O密集型任务,计算密集型任务仍需线程池。
  • Q: 如何选择调度器?
 A: 使用`Dispatchers.IO`进行文件/网络操作,`Dispatchers.Default`用于CPU计算。

总结[编辑 | 编辑源代码]

Kotlin协程通过轻量级的并发模型和结构化并发设计,显著简化了异步编程。掌握`async`/`await`、`Mutex`等工具,能够高效处理并发任务,同时避免常见陷阱如竞态条件。