1、概述
kotlin 协程,自己在项目中用来进行同步串行调用的比较多。 对于并发调用,虽然知道用async,但是也是有些不清晰的,还有asynic 还有个lazy模式。所以写了个简单的例子好理解些。
2、示例
2.1
fun test1() {
GlobalScope.launch {
val old = System.currentTimeMillis()
Log.d("lee", "----test1---")
val a1 = async {
delay(1000)
Log.d("lee", "delay-1000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a2 = async(start = CoroutineStart.LAZY) {
delay(2000)
Log.d("lee", "delay-2000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a3 = async {
delay(3000)
Log.d("lee", "delay-3000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
//a1,a3会直接执行,a2不会
Log.d("lee", "+++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
}
Log.d("lee", "***out***GlobalScope***")
}
输出结果:
2020-06-17 22:32:13.166 4588-4646/com.leon.myapplication D/lee: ----test1---
2020-06-17 22:32:13.175 4588-4588/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:32:13.178 4588-4646/com.leon.myapplication D/lee: +++ timeOff= 0"
2020-06-17 22:32:14.180 4588-4647/com.leon.myapplication D/lee: delay-1000 timeOff= 1
2020-06-17 22:32:16.186 4588-4647/com.leon.myapplication D/lee: delay-3000 timeOff= 3
想表达的结论:非lazy的 async 代码块,会直接执行。lazy的不会执行
2.2
fun test2() {
GlobalScope.launch {
val old = System.currentTimeMillis()
Log.d("lee", "---test2----")
val a1 = async {
delay(1000)
Log.d("lee", "delay-1000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a2 = async(start = CoroutineStart.LAZY) {
delay(2000)
Log.d("lee", "delay-2000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a3 = async {
delay(3000)
Log.d("lee", "delay-3000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
//a1,a3会直接执行,a2不会
Log.d(
"lee",
"同步结果 a1=${a1.await()} a3=${a3.await()} timeOff= ${(System.currentTimeMillis() - old) / 1000L}\""
)
Log.d("lee", "等待结束+++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
}
Log.d("lee", "***out***GlobalScope***")
}
输出
2020-06-17 22:37:00.636 5725-5725/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:37:00.636 5725-5758/com.leon.myapplication D/lee: ---test2----
2020-06-17 22:37:01.640 5725-5759/com.leon.myapplication D/lee: delay-1000 timeOff= 1
2020-06-17 22:37:03.642 5725-5759/com.leon.myapplication D/lee: delay-3000 timeOff= 3
2020-06-17 22:37:03.643 5725-5759/com.leon.myapplication D/lee: 同步结果 a1=28 a3=28 timeOff= 3"
2020-06-17 22:37:03.643 5725-5759/com.leon.myapplication D/lee: 等待结束+++ timeOff= 3"
表达的结论:非lazy的async,调用 await 会阻塞到该事物执行完成
2.3
fun test3() {
GlobalScope.launch {
val old = System.currentTimeMillis()
Log.d("lee", "---test3----")
val a1 = async {
delay(1000)
Log.d("lee", "delay-1000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a2 = async(start = CoroutineStart.LAZY) {
delay(2000)
Log.d("lee", "delay-2000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
val a3 = async {
delay(3000)
Log.d("lee", "delay-3000 timeOff= ${(System.currentTimeMillis() - old) / 1000L}")
}
Log.d(
"lee",
"同步结果 a1=${a1.await()} a3=${a3.await()},timeOff= ${(System.currentTimeMillis() - old) / 1000L}\""
)
Log.d("lee", "开始执行a2, a2是lazy模式,需要显示await才开始执行")
a2.await()
Log.d("lee", "等待结束 +++ timeOff= ${(System.currentTimeMillis() - old) / 1000L}\"")
}
Log.d("lee", "***out***GlobalScope***")
}
2020-06-17 22:39:16.659 6274-6274/com.leon.myapplication D/lee: ***out***GlobalScope***
2020-06-17 22:39:16.659 6274-6309/com.leon.myapplication D/lee: ---test3----
2020-06-17 22:39:17.664 6274-6309/com.leon.myapplication D/lee: delay-1000 timeOff= 1
2020-06-17 22:39:19.668 6274-6309/com.leon.myapplication D/lee: delay-3000 timeOff= 3
2020-06-17 22:39:19.670 6274-6309/com.leon.myapplication D/lee: 同步结果 a1=28 a3=28,timeOff= 3"
2020-06-17 22:39:19.670 6274-6309/com.leon.myapplication D/lee: 开始执行a2, a2是lazy模式,需要显示await才开始执行
2020-06-17 22:39:21.676 6274-6310/com.leon.myapplication D/lee: delay-2000 timeOff= 5
2020-06-17 22:39:21.677 6274-6310/com.leon.myapplication D/lee: 等待结束 +++ timeOff= 5"
想表达的结论:lazy模式的asynic 在调用await的时候才开始执行,并且会在该处阻塞到执行完毕