文章19 | 阅读 9953 | 点赞0
Launches a new coroutine without blocking the current thread.
即不会阻塞当前的线程的运行。我们再来接触一个不一样的协程建造器: runBlocking{}
Runs a new coroutine and blocks the current thread interruptibly until its completion.
核心就是一个单词,block,会阻塞当前线程,这点是和.launch{}是大不相同的,即只有runBlocking中的代码执行完毕后,当前线程才会被唤醒。我们接下来通过代码来感受一下。
fun main() {
GlobalScope.launch {
delay(1000)
println("world")
}
println("hello")
runBlocking {
delay(2000)
}
println("welcome")
}
同样按照之前的时序发展方式,我们来分析一下这段代码:
所以最终的输出结果就是:
hello
(暂停1s)
world
(暂停1s)
welcome
fun main() = runBlocking {
GlobalScope.launch {
delay(1000)
println("world")
}
println("hello")
delay(2000)
println("welcome")
}
输出的结果和之前的例子一样。但是将delay(2000)换成delay(500)结果就不一样了,大家可以去试试,原因的话我们在下一篇去解释。
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job {
....
}
会发现它实际上会返回一个Job类型的引用,何为Job?
A background job. Conceptually, a job is a cancellable thing with a life-cycle that culminates in its completion.
job就是一个待执行的任务,并且能够被取消,有对应的生命周期:New、Active、Completing、Cancelling、Cancelled、Completed.如果非要类比的话,感觉有点像Runnable,并且也是没有返回值的。类似的还有个Deferred,这个是有返回值的,那么这个就有点像Future,后面有专门的篇章再去介绍。今天我们只需要关注它的一个方法:join()
1.Suspends the coroutine until this job is complete.
2.Note that the job becomes complete only when all its children are complete.
这是我从文档上摘取出来的两句:1. 会挂起协程(job的父协程),直到该job执行完毕;2. 只有当某个协程的所有子协程都执行完毕后,才意味着该协程执行完毕。有点抽象,我们来看段代码:
fun main() = runBlocking {
val job = GlobalScope.launch {
delay(1000)
println("world")
}
println("hello")
job.join()
println("welcome")
}
一运行:
hello
(等待1s)
world
welcome
这里先通过runBlocking创建了协程A,在协程A作用域里又通过launch创建了协程B,这样协程B就成了协程A的子协程。这里的job是子协程B的,所以当执行到job.join()这一行时,会挂起父协程A。只有当job执行完毕后,父协程的执行流程才会恢复(resume),所以就能解释上面的输出结果了。读者可以按照我们前面的时序分析法来分析输出结果,我这里就不再赘述了。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xlh1191860939/article/details/98075928
内容来源于网络,如有侵权,请联系作者删除!