coroutines并不在kotlin的标准库中,但kotlin提供了协程支持
使用协程,先引入协程包
Kotlin
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
先来一个简单的协程例子:
Kotlin
fun main() {
runBlocking {
launch {
delay(1000L)
println("LiYunLong!")
}
println("Hello, ")
}
}
runBlocking函数是一个协程构建器,主要作用是将当前函数中的非协程代码协程化,
runBlocking会创建一个CoroutineScope作用域,kotlin协程遵循结构化并发的原则,这意味着新的协程只能在特定的CoroutineScope中启动,
该CoroutineScope限定了协程的生存期外部作用域在其所有子协程完成之前不能完成。
结构化并发性还确保正确报告代码中的任何错误
launch函数也是一个协程构建器
launch的作用是为函数中的代码启动一个并发线程
launch函数只能在CoroutineScope作用域中运行,因此,协程代码须放在runBlocking函数中
dealy是一个特殊的暂停函数(suspend),将当前协程代码延时挂起,挂起的协程代码不会阻塞线程,但允许其它协程代码运行
上面代码运行结果:
bash
Hello,
World!
kotlin自定义协程函数需要使用suspend
Kotlin
fun main() {
runBlocking {
launch {
doName()
}
println("Hello, ")
}
}
private suspend fun doName() {
delay(1000L)
println("LiYunlong!")
}
Kotlin
fun main() {
runBlocking {
doName()
}
}
private suspend fun doName() {
coroutineScope {
launch {
delay(1000L)
println("LiYunlong!")
}
println("Hello, ")
}
}
多个协程进程会同时运行,具体延时时间取决于delay()的值参
Kotlin
fun main() {
runBlocking {
doName()
}
}
private suspend fun doName() {
coroutineScope {
launch {
delay(3000L)
println("LiYunLong")
}
launch {
delay(2000L)
println("YunFeiXiong")
}
launch {
delay(1000L)
println("DaBiao")
}
launch {
delay(2000L)
println("ZhengWei")
}
println("Hello, ")
}
}
YunFeiXiong和ZhengWei的delay时间都是2000L,因此YunFeiXiong和ZhengWei会同时弹出
Kotlin
DaBiao
YunFeiXiong
ZhengWei
LiYunLong
协程比进程占用更少的资源,并且协程拥有更少哦的资源限制
Kotlin
coroutineScope {
repeat(5000000){//同时启用5000000个协程进程轻轻松松
launch {
delay(1000)
println("'._")
}
}
}
和launch一样async也是一个协程构建器
不同的是,launch不返回特定结果,而async会返回一个期望的结果
下面以OkHttp爬取一个网页为例:
Kotlin
fun main() {
runBlocking {
getBaidu()
}
}
private suspend fun getBaidu(){
coroutineScope {
launch {
delay(1000L)
request("https://baidu.com","BAIDUID=*; PSTM=1729731690")
}
println(async {
delay(1000L)
// 请把Cookie换成自己浏览器捕捉到的
request("https://baijiahao.baidu.com/s?id=1813752803356680783&wfr=spider&for=pc","BAIDUID=*; PSTM=1729731690")
}.await())
println(launch {
delay(1000L)
request("https://baijiahao.baidu.com/s?id=1813752803356680783&wfr=spider&for=pc","BAIDUID=*; PSTM=1729731690")
})
}
}
private fun request(url:String, cookie:String):String{
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
.addHeader("Cookie", cookie)
.build()
val response:Response = client.newCall(request).execute()
return response.body?.string().toString()
}
执行上面代码,只有async会打印返回结果,而launch函数则只是默默付出