美文网首页
6.协程的挂起

6.协程的挂起

作者: 学吉他的袁先生 | 来源:发表于2020-08-10 08:58 被阅读0次

挂起函数的作用以及使用场景:
挂起函数会让协程从正在执行它的线程上脱离,并在挂起函数执行结束恢复到原线程,实现非阻塞式挂起。
可用于耗时的函数比如联网获取数据,数据库读写,文件io等
1.标准挂起函数应该定义线程切换,取消机制,结果返回三个部分
retrofit2.7.1里面部分源码KotlinExtensions.class

@JvmName("awaitNullable")
suspend fun <T : Any> Call<T?>.await(): T? {
  return suspendCancellableCoroutine { continuation ->
    continuation.invokeOnCancellation {
      cancel()
    }
    enqueue(object : Callback<T?> {
      override fun onResponse(call: Call<T?>, response: Response<T?>) {
        if (response.isSuccessful) {
          continuation.resume(response.body())
        } else {
          continuation.resumeWithException(HttpException(response))
        }
      }

      override fun onFailure(call: Call<T?>, t: Throwable) {
        continuation.resumeWithException(t)
      }
    })
  }
}

2.如何自定义挂起函数
仅仅依靠suspend修饰符是改变不了线程的

suspend fun getUser():String{
    log("getUser")
    return ""
}
suspend fun main(){
    getUser()
}

打印:

16:07:05:167 [main,1] getUser

示例1 只有返回值跟切换线程

suspend fun getUserInIo()= withContext(Dispatchers.IO){
    "hhahah"
}
suspend fun main(){
    GlobalScope.launch {
        val userInIo = getUserInIo()
        log(userInIo)
    }.join()
}

打印:

16:23:50:267 [DefaultDispatcher-worker-3,14] hhahah

示例 不做线程切换,依靠协程做切换

suspend fun getUser1()= suspendCoroutine<String> {
    //直接使用当前协程所在的线程,不做切换
    it.resume("hhahahah")
}
suspend fun main(){
    val user1 = getUser1()
    log(user1)
    GlobalScope.launch {
        log(1)
        val user11 = getUser1()
        log(user1)
        withContext(Dispatchers.IO){
            val user11 = getUser1()
            log(user1)
        }
    }.join()
}

示例
既做线程切换,又有取消

suspend fun getUserInFile()= suspendCancellableCoroutine<Int> {
    var threadStop=true
    it.invokeOnCancellation {
        //如果没有这个,那么挂起函数是无法取消的
        threadStop=false
    }
    thread (name = "hahaha"){
        //模拟耗时操作
        try {
            var i=0;
            while (threadStop&&i<1000){
                Thread.sleep(100)
                i++
                log(i)
            }
            it.resume(i)
        }catch (e: Exception){
            it.resumeWithException(e)
        }
    }
}
suspend fun main(){
    val launch = GlobalScope.launch{
        log("start")
        val userInFile = getUserInFile()
        log(userInFile)
    }
    delay(1000)
    launch.cancel()
    delay(1000)
}

相关文章

  • 6.协程的挂起

    挂起函数的作用以及使用场景:挂起函数会让协程从正在执行它的线程上脱离,并在挂起函数执行结束恢复到原线程,实现非阻塞...

  • 破解 Kotlin 协程(6) - 协程挂起篇

    关键词:Kotlin 协程 协程挂起 任务挂起 suspend 非阻塞 协程的挂起最初是一个很神秘的东西,因为我们...

  • Kotlin协程挂起函数与全局协程实例分析

    Kotlin协程挂起函数与全局协程实例分析 挂起函数【suspend】 这是因为 delay 是一个特殊的 挂起函...

  • Kotlin 协程之基础

    这里因为 delay 是一个特殊的 挂起函数 ,它不会造成挂起线程,但是会 挂起 协程,并且只能在协程中使用。 普...

  • 协程(2)-协程的挂起

    在上一期里,我介绍了 Kotlin 的协程到底是什么——它就是个线程框架。没什么说不清的,就这么简单,它就是个线程...

  • Kotlin 协程入门

    本文主要介绍协程长什么样子, 协程是什么东西, 协程挂起的实现原理以及整理了协程学习的资料. 协程 HelloWo...

  • 协程.md

    协程协程中使用suspend修饰方法,代表该方法可在协程中挂起。但并不是协程方法必须使用suspend修饰协程和线...

  • swoole协程channel元素个数

    channel用于进程内跨协程通讯,按照角色分为生产协程和消费协程。生产协程,在channel已满时,会被挂起;消...

  • Kotlin协程(2):挂起函数的原理

    一 挂起函数的运行逻辑 挂起函数用状态机以挂起点将协程的运算逻辑拆分成不同的片段,每次执行协程运行不同的逻辑片段,...

  • kotlin协程的使用与原理

    协程 协程是轻量级线程,一个线程中可以有很多协程,协程本质上可以认为是运行在线程上的代码块,协程提供的挂起操作会使...

网友评论

      本文标题:6.协程的挂起

      本文链接:https://www.haomeiwen.com/subject/uoncdktx.html