GlobalScope.launch(Dispatchers.Main) 是否立即执行?
kotlin吧
全部回复
仅看楼主
level 1
11amok 楼主
执行这段代码,会发现输出1,3后就无响应了。
把第一行runBlocking改为GlobalScope.launch(Dispatchers.Main), 会正常输出1,3,2,4
通过这些现象,是否可以得出以下结论?:GlobalScope.launch(Dispatchers.Main) 启动的协程并不会马上执行,而是继续执行主线程后面的代码,直到空闲的时候才会运行该协程。
我的分析是,无响应是因为join的时候,让runBlocking这个协程挂起了,阻塞主线程。然而打印2的协程压根就还没执行,所以无限等待了。第一行改为GlobalScope.launch(Dispatchers.Main) 的话,join时挂起,不阻塞主线程,于是继续执行打印2的协程。2输出以后,挂起恢复,继续执行println("4")
runBlocking {
println("1")
val job = GlobalScope.launch(Dispatchers.Main) {
println("2")
}
println("3")
job.join()
println("4")
}
2020年01月09日 08点01分 1
level 1
兄弟线程也是依附于线程的,怎么给你解释呢。线程任务是个队列,你开起的是主线程的任务。所以在主线程第一个任务没有执行完的情况下。你阻塞了主线程,然后就无法再启动第二个任务,所以1,3之后就卡死了。这个可以说是一个类死锁的操作。当你在外部再建一个任务,这时候第一个任务在外部就已经执行完了,然后开启第二个任务,你只是把第二个协程任务给阻塞了,这时候系统发现你是在协程里面于是开启第3个任务继续执行。然后第3个任务执行完了,第二个的锁打开了,第二个任务继续执行。这个和java是相通的。这样去理解是不是要好点呢?
2020年03月23日 03点03分 3
是的,跟踪了下GlobalScope.launch(Dispatchers.Main)源码,是通过handler post任务到主线程的looper队列里的,这个job其实还没有执行。任务1又阻塞了再等待这个job,确实相当于死锁了
2020年03月25日 05点03分
level 1
这就是在不在协程里面执行的区别。阻塞的话都是主线程。只要你把协程和线程的关系搞清楚。这些都不是问题。不要把协程和线程混为一起了。网上很多教学仔细看实际是有很多错误的信息最好在官网学习,结合自己的java基础很容易上手的
2020年03月23日 03点03分 4
1