找回密码
 立即注册
首页 业界区 安全 Kotlin协程实战:比Java线程更优雅的并发编程 ...

Kotlin协程实战:比Java线程更优雅的并发编程

蜴间囝 4 小时前
前言

Kotlin 协程(Coroutines)是 Android 和服务端开发者的必备技能。相比 Java 线程,协程更轻量、更易读、更安全。本文带你从零掌握 Kotlin 协程的核心用法。
一、协程 vs 线程


  • 线程:操作系统调度,创建成本高(约1MB栈内存)
  • 协程:用户态调度,创建成本极低(约几KB),可创建数十万个
  1. // Java 线程:10000个线程会OOM
  2. for (int i = 0; i < 10000; i++) {
  3.     new Thread(() -> doWork()).start();
  4. }
  5. // Kotlin 协程:100000个协程轻松运行
  6. repeat(100_000) {
  7.     GlobalScope.launch { doWork() }
  8. }
复制代码
二、第一个协程
  1. import kotlinx.coroutines.*
  2. fun main() = runBlocking {
  3.     // 启动协程
  4.     launch {
  5.         delay(1000)  // 非阻塞延迟
  6.         println("World!")
  7.     }
  8.     println("Hello,")
  9. }
  10. // 输出:
  11. // Hello,
  12. // (1秒后) World!
复制代码
三、协程作用域(CoroutineScope)
  1. // 1. GlobalScope:全局作用域,生命周期跟随应用
  2. GlobalScope.launch {
  3.     println("Global scope")
  4. }
  5. // 2. runBlocking:阻塞当前线程直到协程完成
  6. runBlocking {
  7.     launch { println("runBlocking") }
  8. }
  9. // 3. coroutineScope:挂起当前协程,等待子协程完成
  10. suspend fun loadData() = coroutineScope {
  11.     launch { fetchUser() }
  12.     launch { fetchOrders() }
  13. }
  14. // 4. ViewModelScope(Android):跟随 ViewModel 生命周期
  15. viewModelScope.launch {
  16.     val data = repository.fetchData()
  17.     updateUI(data)
  18. }
复制代码
四、挂起函数(suspend)
  1. // 挂起函数:可在协程中暂停执行,不阻塞线程
  2. suspend fun fetchUser(): User {
  3.     return withContext(Dispatchers.IO) {
  4.         // 切换到 IO 线程执行网络请求
  5.         api.getUser()
  6.     }
  7. }
  8. // 调用挂起函数
  9. fun loadData() = viewModelScope.launch {
  10.     showLoading()
  11.     val user = fetchUser()  // 挂起,等待结果
  12.     updateUI(user)          // 恢复执行
  13.     hideLoading()
  14. }
复制代码
五、协程调度器(Dispatcher)
  1. // 1. Dispatchers.Main:主线程(UI 操作)
  2. withContext(Dispatchers.Main) {
  3.     textView.text = "Updated"
  4. }
  5. // 2. Dispatchers.IO:IO 密集型(网络、数据库)
  6. withContext(Dispatchers.IO) {
  7.     val data = api.fetchData()
  8.     database.save(data)
  9. }
  10. // 3. Dispatchers.Default:CPU 密集型(排序、计算)
  11. withContext(Dispatchers.Default) {
  12.     val sorted = list.sortedBy { it.id }
  13. }
  14. // 4. 自定义线程池
  15. val customDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
  16. withContext(customDispatcher) {
  17.     heavyComputation()
  18. }
复制代码
六、异常处理
  1. // CoroutineExceptionHandler:全局异常捕获
  2. val handler = CoroutineExceptionHandler { _, e ->
  3.     println("Caught: $e")
  4. }
  5. val job = GlobalScope.launch(handler) {
  6.     throw RuntimeException("Error!")
  7. }
  8. // try-catch:局部异常处理
  9. try {
  10.     val result = async {
  11.         riskyOperation()
  12.     }.await()
  13. } catch (e: Exception) {
  14.     handleError(e)
  15. }
复制代码
七、实战:并发请求
  1. data class User(val id: Int, val name: String)
  2. data class Order(val id: Int, val userId: Int)
  3. suspend fun loadUserData(userId: Int): Pair<User, List<Order>> {
  4.     return coroutineScope {
  5.         // 并发执行两个请求
  6.         val userDeferred = async { fetchUser(userId) }
  7.         val ordersDeferred = async { fetchOrders(userId) }
  8.         
  9.         // 等待结果
  10.         Pair(userDeferred.await(), ordersDeferred.await())
  11.     }
  12. }
  13. // 对比 Java CompletableFuture
  14. // Kotlin 协程写法更简洁,无需回调链
复制代码
总结

Kotlin 协程让并发编程变得优雅。核心要点:


    • 轻量级:可创建数十万协程而不 OOM

结构化并发

      :作用域自动管理协程生命周期

挂起函数

      :用同步写法实现异步逻辑

调度器
    :灵活切换线程,适配不同场景

觉得有帮助请点赞收藏!有问题欢迎评论区交流
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册