Kotlin 协程(三)协程的常用关键字使用及其比力

打印 上一主题 下一主题

主题 1042|帖子 1042|积分 3126

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在使用协程时,经常会用到suspend、launch、async、await、withContext、runBlocking这些关键字,这儿对其举行表明和比力
为了更好地理解 suspend、launch、async、await、withContext、runBlocking 之间的区别,我们可以从 挂起、协程启动、作用域管理 等方面举行对比。
1. suspend 关键字(挂起与规复)



  • suspend 关键字用于 定义挂起函数,体现该函数可以在非壅闭的环境下停息(挂起)并规复。
  • 挂起函数只能在 协程或其他挂起函数 中调用。
  • 挂起时不会壅闭线程,而是让出线程,允许其他协程实行。
2. launch(启动一个新的协程,返回 Job)



  • launch 创建 并启动一个新的协程 但不会返回效果
  • 适用于 不须要返回值,比方更新 UI、写日志等。
  • 返回一个 Job,可以用 job.cancel() 取消该协程。
3. async & await(并发实使用命,返回 Deferred<T>)



  • async 启动 并发使命 并返回一个 Deferred<T>(雷同于 Future)。
  • await() 用于获取 async 返回的效果,如果使命未完成,它会挂起协程直到完成。
  1. suspend fun loadData(): String {
  2.     return withContext(Dispatchers.IO) {
  3.         delay(1000)
  4.         "Data loaded"
  5.     }
  6. }
  7. suspend fun testAsync() {
  8.     val deferred1 = async { loadData() }
  9.     val deferred2 = async { loadData() }
  10.     // await() 取出结果
  11.     val result1 = deferred1.await()
  12.     val result2 = deferred2.await()
  13.    
  14.     println("Result: $result1, $result2")
  15. }
复制代码


  • 须要 并行实行多个使命 并等待效果:

    • 多个网络请求
    • 批量数据库查询
    • 盘算密集型使命

   async 雷同于 launch,但它返回效果,launch 只是实行,不返回值。
  4. withContext(切换协程上下文,实行完成后返回效果)



  • withContext 切换 到指定的调度器(线程池),实行代码块,并返回效果。
  • 等待代码块实行完成后再继续,不会创建新的协程,而是挂起当前协程并切换线程
  1. suspend fun fetchData(): String {
  2.     return withContext(Dispatchers.IO) {  // 切换到 IO 线程
  3.         delay(1000)
  4.         "Fetched Data"
  5.     }
  6. }
复制代码


  • 切换线程池,适用于:

    • 网络请求(Dispatchers.IO)
    • 数据库查询(Dispatchers.IO)
    • 盘算密集型使命(Dispatchers.Default)

   withContext 不会并发实行,它只是切换线程,等使命完成后再返回。
  Dispatchers 预定义调度器
调度器作用适用场景Dispatchers.Default适用于 CPU 密集型使命(盘算、加密等)盘算使命,如排序、数学运算等Dispatchers.IO适用于 I/O 操作(磁盘、网络、数据库)读写文件、数据库查询、网络请求Dispatchers.Main适用于 Android 主线程更新 UI,处理用户交互Dispatchers.Unconfined继续调用方线程,规复时可能切换线程测试或暂时使命,不发起使用newSingleThreadContext("MyThread")自定义单线程调度器特定线程实使用命 5. launch vs async vs withContext 对比

关键字是否返回效果适用场景线程调度launch❌ 不返回效果实使用命但不关心效果不切换线程async✅ 返回 Deferred<T>并发实行多个使命并等待效果不切换线程withContext✅ 返回效果切换线程并实使用命切换线程
6.runBlocking 详解

runBlocking 是 Kotlin 协程中的一个函数,它 壅闭当前线程 并运行一个新的协程,直到该协程及其子协程实行完毕后才会继续实行后续代码。一般不会用到,只要用于测试
  1. fun main() {
  2.     runBlocking {
  3.         println("协程开始")
  4.         delay(1000)
  5.         println("协程结束")
  6.     }
  7.     println("主线程继续执行")
  8. }
复制代码
实行流程

  • runBlocking 启动 一个协程 并壅闭当前线程(如 main 线程)。
  • delay(1000) 挂起协程,但 runBlocking 仍然壅闭 线程,其他代码不会实行。
  • 协程实行完 delay(1000) 之后,继续实行 println("协程结束")。
  • runBlocking 结束后,主线程才会继续实行 println("主线程继续实行")。
  1. fun main() {
  2.     runBlocking {
  3.         launch {
  4.             delay(1000)
  5.             println("子协程完成")
  6.         }
  7.         println("runBlocking 结束")
  8.     }
  9.     println("主线程继续")
  10. }
复制代码
实行流程

  • runBlocking 启动 一个主协程,壅闭 main 线程。
  • launch 创建一个子协程,但 launch 不会壅闭 runBlocking,它只是异步实行。
  • println("runBlocking 结束") 立即实行,不等待 launch 内部的 delay(1000) 。
  • runBlocking 结束后,main 线程继续实行 println("主线程继续")。
  • launch 子协程在背景继续运行,1 秒后打印 "子协程完成"。
7.启动新协程

关键字作用返回值是否壅闭线程适用于launch启动一个新的协程,异步实行代码Job❌ 否得当不须要返回值的使命async启动一个新的协程,返回 DeferredDeferred<T>❌ 否得当须要返回值的使命 8. 作用域管理

关键字作用是否壅闭线程适用于runBlocking壅闭当前线程,启动协程✅ 是main 函数、单位测试coroutineScope创建新的协程作用域,等待全部子协程完成❌ 否挂起函数内部管理协程withContext在指定调度器中切换上下文并实行代码❌ 否线程切换(如 IO 线程) 总结

关键字作用是否壅闭线程是否创建新协程适用于suspend让函数支持挂起❌ 否❌ 否定义可挂起函数launch启动一个协程,无返回值❌ 否✅ 是异步实行无返回值使命async启动一个协程,返回 Deferred<T>❌ 否✅ 是盘算使命,须要返回值await挂起当前协程,等待 async 效果❌ 否❌ 否获取 async 效果runBlocking启动协程并壅闭线程✅ 是✅ 是main 函数、测试coroutineScope创建作用域,等待全部协程❌ 否❌ 否在挂起函数内部管理协程withContext切换协程实行的线程❌ 否❌ 否线程切换,如 Dispatchers.IO

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

北冰洋以北

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表