请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于Delay和挂起

  1. 首先挂起,该如何去理解?什么是挂起?举个例子。我在UI主线程请求网络,在方法中开启一个协程去请求。在不阻塞的情况下,请求线程挂起等待请求结果,主线程继续执行。等结果回来返回到主线程。这个叫挂起?
  2. 视频和例子都存在挂起点执行后main方法执行完,导致协程耗时操作之后数据打印不出来。那这不是BUG吗?我用协程请求数据,然后数据回来我用不了?(这个问题是GlobalScope.launch。必须加Join,想要结果用GlobalScope.async)
  3. 这个Delay到底是什么作用?首先他是个挂起点,之前视频里提到过。delay之后的代码会执行delay创建的的线程。但是实际是可能在一个线程可能不再一个线程图片描述图片描述
    图片描述
    图片描述
    老师请帮我分析下这4中情况输出的结果。感觉完全不符合预期。尤其第二张图片
  4. 我想知道Join.start()不是挂起点。Join.join是挂起点为什么图片描述图片描述
    协程视屏这节 越看越懵抓不到重点。听的很混乱

正在回答

插入代码

1回答

  1. 挂起不是协程的特有的说法,操作系统层面会对任务调度过程中被中断后的状态叫做挂起。如果对挂起不理解,建议补充些操作系统的进程和线程调度的知识哈。

    “在不阻塞的情况下,请求线程挂起等待请求结果,主线程继续执行。等结果回来返回到主线程。这个叫挂起?”

    结果回来就是恢复执行了,挂起是前面半句描述的情况。

  2. “视频和例子都存在挂起点执行后main方法执行完,导致协程耗时操作之后数据打印不出来。那这不是BUG吗?我用协程请求数据,然后数据回来我用不了?(这个问题是GlobalScope.launch。必须加Join,想要结果用GlobalScope.async)”

    这不是bug,是因为main函数执行完以后,主线程结束,如果剩下的运行中的异步任务的线程是幽灵线程的话 Java 虚拟机就会直接退出。所以如果你希望在主线程里用到结果,那就 join 或者 await 一下。

  3. delay 是个挂起函数,挂起后当前协程就不执行了,delay会在指定时间之后来恢复当前协程的执行,恢复的时候如果当前协程没有指定调度器,那么调度器就是默认调度器(背后是个线程池),那么当前线程会调度到这个线程池上执行,那么具体是哪个线程取决于当时的实际情况。图1和图2的结果其实没有什么本质区别,图2 delay 前后的日志在相同的线程打印出来其实表明delay后恢复时线程池恰好可以用这个线程来调度这个任务而已。

    图3的情况跟前面不太一样,delay执行在 suspend fun main 当中,这个协程没有调度器,所以不会产生调度行为,而是直接运行在 delay 恢复的唤醒线程上。图4类似。

  4. Job.start 是告诉 Job 可以开始执行了,Job.join 需要等待 Job 执行完才能继续执行,这两个里面一个逻辑上没有等待,一个逻辑上存在等待。这两个函数跟 Thread 的  start  和 join 的作用几乎一样,它的 start 同样立即返回,join 要阻塞当前线程(对应的协程的 join 就是挂起当前协程)。


协程本身是语言层面的东西,自然就基于了底层的操作系统、线程这样的概念,从同学的问题来看,对于线程池、线程、操作系统的一些概念的理解还需要继续加强哈,不然肯定会影响你对协程的理解的。

2 回复 有任何疑惑可以回复我~
  • 提问者 慕妹2978617 #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2019-12-20 14:08:06
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号