Kotlin的协程可以理解为一个轻量级的线程,如下是一个协程
示例(1):
fun main() {
GlobalScope.launch { // 启动协程
delay(2000) // 挂起2秒钟
println("协程执行了...")
}
println("Hello")
Thread.sleep(3000) // 阻塞3秒钟
println("World")
}
如上的执行结果为:
Hello
协程执行了...
World
如果把Thread.sleep(3000)改为Thread.sleep(1500),执行结果为:
Hello
World
这是因为main已经不存活了,生命走完了,所以协程内的println("协程执行了...")没有执行.delay是一个非阻塞的挂起函数.
示例(2):
fun main() {
GlobalScope.launch { // 启动协程
delay(1000)
println("协程执行了...")
}
println("Hello")
runBlocking {
delay(2000)
}
println("World")
}
如上输出结果为:
Hello
协程执行了...
World
示例(2)使用 runBlocking 协程构建器来阻塞主线程,输出结果与示例(1)相似.runBlocking会一直阻塞到runBlocking内部的协程执行完毕,即阻塞到delay函数执行完毕.
通过示例(1)和示例(2),我们可以把协程优化为示例(3)
示例(3)
fun main() = runBlocking {
GlobalScope.launch { // 启动协程
delay(1000)
println("协程执行了...")
}
println("Hello")
delay(2000)
println("World")
}
如上输出结果为:
Hello
协程执行了...
World
示例(3)的执行结果和示例(2)完全一样,示例(3)通过runBlocking来启动顶层主协程的适配器
示例(4):
fun main() = runBlocking {
val job = GlobalScope.launch { // 启动协程
delay(1000)
println("协程执行了...")
}
println("Hello")
job.join()
println("World")
}
如上输出结果为:
Hello
协程执行了...
World
示例(4)是通过GlobalScope.launch返回的是一个job,然后通过job.join()来暂停使得job内部的协程得到执行
示例(5):
fun main() = runBlocking {
launch { // 在 runBlocking 作用域中启动一个新协程
delay(1000)
println("job1")
}
println("Hello")
coroutineScope { // 创建一个协程作用域
launch {
delay(10000)
println("job2")
}
delay(3000)
println("World")
}
println("Hello World")
}
如上输出结果为:
Hello
job1
World
job2
Hello World
从示例(5)的输出结果,可以看出runBlocking是非挂起的阻塞函数,coroutineScope是挂起不阻塞的函数.
二者都有对应的作用域,在作用域内都会等待其协程体以及所有子协程结束
网友评论