Kotlin 协程启动方式

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

一、协程启动方式

二、启动方式详解

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

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

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

特点

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

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

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

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

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

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

特点

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

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

  • 支持并行任务:

    Kotlin 复制代码
    val result1 = async { fetchDataFromAPI1() }
    val result2 = async { fetchDataFromAPI2() }
    val combined = result1.await() + result2.await()

3. runBlocking - 阻塞式启动协程

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

特点

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

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

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

三、启动参数配置

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

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

四、启动方式对比表

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

五、实践使用

  • 网络请求组合

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

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

    Kotlin 复制代码
    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
相关推荐
CodeSheep程序羊8 分钟前
拼多多春节加班工资曝光,没几个敢给这个数的。
java·c语言·开发语言·c++·python·程序人生·职场和发展
独好紫罗兰8 分钟前
对python的再认识-基于数据结构进行-a002-列表-列表推导式
开发语言·数据结构·python
I'mChloe16 分钟前
PTO-ISA 深度解析:PyPTO 范式生成的底层指令集与 NPU 算子执行的硬件映射
c语言·开发语言
编程小白202628 分钟前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
像风一样的男人@1 小时前
python --读取psd文件
开发语言·python·深度学习
输出输入1 小时前
前端核心技术
开发语言·前端
加油,小猿猿1 小时前
Java开发日志-双数据库事务问题
java·开发语言·数据库
薛定谔的猫喵喵1 小时前
天然气压力能利用系统综合性评价平台:基于Python和PyQt5的AHP与模糊综合评价集成应用
开发语言·python·qt
独好紫罗兰1 小时前
对python的再认识-基于数据结构进行-a004-列表-实用事务
开发语言·数据结构·python
gjxDaniel1 小时前
Objective-C编程语言入门与常见问题
开发语言·objective-c