Kotlin 协程启动方式

发布于:2025-08-15 ⋅ 阅读:(16) ⋅ 点赞:(0)

在 Kotlin 协程中,主要有三种核心启动方式,每种方式都有其特定的使用场景和特点:

一、协程启动方式

二、启动方式详解

1. launch - 启动不需要返回结果的协程

val job = CoroutineScope(Dispatchers.IO).launch {
    // 执行异步操作
    delay(1000)
    println("任务完成")
}

// 控制协程生命周期
job.cancel() // 取消协程
job.join()   // 等待协程完成

特点

  • 返回 Job 对象(无结果值)

  • Fire-and-forget 模式(发后即忘)

  • 适用于后台任务(日志上传、缓存清理等)

2. async - 启动需要返回结果的协程

val deferred = CoroutineScope(Dispatchers.Default).async {
    // 执行计算任务
    delay(1000)
    42 // 返回计算结果
}

// 获取结果(会挂起当前协程)
val result = deferred.await()
println("计算结果: $result")

特点

  • 返回 Deferred<T> 对象(继承自 Job)

  • 通过 await() 获取结果(会挂起当前协程)

  • 支持并行任务:

    val result1 = async { fetchDataFromAPI1() }
    val result2 = async { fetchDataFromAPI2() }
    val combined = result1.await() + result2.await()

3. runBlocking - 阻塞式启动协程

fun main() {
    runBlocking {
        // 在阻塞协程中执行
        delay(1000)
        println("主线程阻塞1秒")
    }
    println("程序继续执行")
}

特点

  • 阻塞当前线程直到协程完成

  • 主要用于测试、main函数和桥接阻塞代码

  • 禁止在UI线程使用(会导致ANR)

三、启动参数配置

所有启动函数都支持 start 参数:

launch(start = CoroutineStart.LAZY) {
    // 延迟启动的协程
}
启动模式 行为描述 使用场景
DEFAULT 立即调度执行(默认) 大多数情况
LAZY 仅在需要时启动(手动调用start/join/await触发) 条件触发任务
ATOMIC 原子性启动(不可取消) 关键初始化操作
UNDISPATCHED 立即在当前线程执行首段代码 优化上下文切换

四、启动方式对比表

特性 launch async runBlocking
返回类型 Job Deferred<T> T(泛型结果)
是否阻塞线程 非阻塞 非阻塞 阻塞当前线程
结果获取 无返回值 await() 获取结果 直接返回结果
异常处理 异常会传播到父协程 异常在await时抛出 异常直接抛出
适用场景 后台任务、事件触发 并行计算、结果聚合 测试、main函数、脚本
取消传播 通过Job控制 通过Deferred控制 不可取消
生命周期 随作用域结束自动取消 随作用域结束自动取消 执行完成后自动结束

五、实践使用

  • 网络请求组合

    suspend fun fetchCombinedData(): CombinedResult = coroutineScope {
        val user = async { api.getUser() }
        val posts = async { api.getPosts() }
        CombinedResult(user.await(), posts.await())
    }
  • 超时控制

    val result = withTimeoutOrNull(3000) {
        async { longRunningTask() }.await()
    } ?: fallbackValue
  • 任务编排

    val job = launch {
        val step1 = async { doStep1() }
        val step2 = async { doStep2(step1.await()) }
        val step3 = async { doStep3(step2.await()) }
        processFinalResult(step3.await())
    }

七、常见问题总结

Q:请解释Kotlin协程的启动方式及其区别?

A

“Kotlin协程有三种核心启动方式:

1. launch - 任务执行器

  • 返回Job对象,用于控制协程生命周期

  • 不返回结果,适用于'发后即忘'场景

  • 示例:后台日志上传、定时清理任务

2. async - 结果获取器

  • 返回Deferred<T>(继承Job),通过await()获取结果

  • 支持并行任务组合,如并发网络请求

  • 示例:同时获取用户资料和好友列表

3. runBlocking - 阻塞桥接器

  • 阻塞当前线程直到协程完成

  • 主要用于测试、main函数和桥接阻塞代码

  • 禁止在Android主线程使用(会导致ANR)

关键区别

维度 launch async runBlocking
返回值
阻塞性 非阻塞 非阻塞 阻塞
使用场景 后台任务 结果聚合 测试/main

网站公告

今日签到

点亮在社区的每一天
去签到