Kotlin 异步编程入门
现代应用程序需要高性能和快速响应。异步编程允许你在不阻塞主执行线程的情况下执行耗时操作(网络请求、文件读取、数据库操作)。在 Kotlin 中,使用名为协程的强大而优雅的机制来实现这一目的。
与传统线程不同,协程是轻量级的,在语言层面进行管理,并且不需要巨大的系统资源。这使得它们成为编写易读、易维护的异步代码的理想工具。在本指南中,我们将从头开始分解 Kotlin 中异步编程的核心概念。
1. 协程基础:它们是什么以及如何工作
协程是一个可挂起计算的实例。它可以在代码中的某一点挂起,在另一点恢复,而不会阻塞线程。要使用协程,你需要添加 kotlinx.coroutines 库。
添加依赖
将以下内容添加到你的 build.gradle.kts 文件中:
dependencies { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")}你的第一个协程
要启动协程,请使用 launch 构建器。它会在后台启动一个新协程。
import kotlinx.coroutines.*
fun main() = runBlocking { // runBlocking 会阻塞主线程以等待协程 println("开始:${Thread.currentThread().name}")
launch { // 启动一个新协程 delay(1000L) // 挂起 1 秒(不会阻塞线程!) println("协程:${Thread.currentThread().name}") }
println("结束:${Thread.currentThread().name}")}输出:
开始:main结束:main协程:main注意:delay 是一个挂起函数,它会挂起协程但不会阻塞线程。当协程“睡眠”时,线程可以执行其他代码。
2. 挂起函数:异步的构建块
挂起函数是一种可以挂起并在以后恢复的函数。此类函数只能从其他挂起函数或协程内部调用。它们使用 suspend 关键字进行标记。
挂起函数示例
import kotlinx.coroutines.*
suspend fun fetchData(): String { delay(2000L) // 模拟一个长时间的网络请求 return "数据已接收"}
fun main() = runBlocking { println("请求数据中...") val result = fetchData() // 从协程中调用挂起函数 println(result)}使用 async/await 并行执行
如果你需要并行执行多个任务,请使用 async 构建器。它返回一个持有未来结果的 Deferred 对象。你可以使用 await() 检索结果。
import kotlinx.coroutines.*
suspend fun loadUser(): String { delay(1000L) return "用户:Ivan"}
suspend fun loadPosts(): String { delay(1500L) return "帖子:新闻,文章"}
fun main() = runBlocking { val time = measureTimeMillis { val userDeferred = async { loadUser() } val postsDeferred = async { loadPosts() }
println(userDeferred.await()) println(postsDeferred.await()) } println("总时间:$time ms") // ~1500 毫秒(两者中的最大时间)}如果没有 async,任务将顺序执行,耗时约 2500 毫秒。并行执行将时间减少到约 1500 毫秒。
3. 调度器:管理线程
调度器决定了协程将在哪个线程或线程池上执行。