-
delay 函数是一个非阻塞式挂起函数,它可以让当前协程延迟到指定的时间执行,且只能在协程的作用域或者其他挂起函数中调用
-
对比 Thread.sleep() 函数,delay 函数只会挂起当前协程,并不会影响其他协程的运行,而 Thread.sleep() 函数会阻塞当前线程,那么该线程下的所有协程都会被阻塞
fun main() {
GlobalScope.launch {
println(“codes run in coroutine scope”)
}
}
上述代码你运行一下会发现日志打印不出来,小朋友,你是否有很多问号?😂
这是因为代码块中的代码还没来得及执行,应用程序就结束了,要解决这个问题,我们可以让程序延迟一段时间在结束,如下:
fun main() {
GlobalScope.launch {
println(“codes run in coroutine scope”)
}
Thread.sleep(1000)
}
//打印结果
codes run in coroutine scope
上述代码我们让主线程阻塞了 1 秒钟在执行,因此代码块中的代码得到了执行。其实这种写法还是存在一点问题,如果我让代码块中的代码在 1 秒钟内不能运行结束,那么就会被强制中断:
fun main() {
GlobalScope.launch {
println(“codes run in coroutine scope”)
delay(1500)
println(“codes run in coroutine scope finished”)
}
Thread.sleep(1000)
}
//打印结果
codes run in coroutine scope
上述代码我们在代码块中加入了一个 delay 函数,并在其之后又打印了一行日志。那么当前协程会挂起 1.5 秒,而主线程却只阻塞了 1 秒,那么重新运行一下程序,新增的这条日志并没有打印出来,因为它还没来得及运行,程序就结束了。
那有办法让协程中所有的代码都执行完了之后在结束吗?🤔️
答:有的,使用 runBlocking 函数
五、使用 runBlocking 函数创建一个能阻塞当前线程的协程作用域
- runBlocking 函数可以保证在协程作用域内的所有代码和子协程没有全部执行完之前一直阻塞当前线程
注意:runBlocking 函数通常只能在测试环境中使用,在正式环境中使用会容易产生一些性能上的问题
fun main() {
runBlocking {
println(“codes run in coroutine scope”)
delay(1500)
println(“codes run in coroutine scope finished”)
}
}
//打印结果
codes run in coroutine scope
codes run in coroutine scope finished
上述代码我们使用了 runBlocking 函数,可以看到两条日志都能够正常打印出来了。到了这里我心里会有一个疑问:上面的代码都是跑在同一个协程中,我能不能创建多个协程同时跑呢?
答:可以的,使用 launch 函数
六、使用 launch 函数在当前的协程作用域下创建子协程
上面我们讲到过,launch 函数是 CoroutineScope 的一个扩展函数,因此只要拥有协程作用域,就可以调用 launch 函数
- 单独使用 launch 函数和我们刚才使用的 GlobalScope.launch 函数不同, GlobalScope.launch 创建的是一个顶级协程,而 launch 函数创建的是子协程
fun main() {
runBlocking {
launch {
println(“launch1”)
delay(1000)
println(“launch1 finished”)
}
launch {
println(“launch2”)
delay(1000)
println(“launch2 finished”)
}
}
}
//打印结果
launch1
launch2
launch1 finished
launch2 finished
上述代码我们调用了两次 launch 函数,也就是创建了两个子协程,