簡介
介紹
此篇文章主要介紹了kotlin組合掛起函數(shù),如果之前沒有接觸過協(xié)程冻河,可以參考下面的文章目錄
參考文檔
文章目錄
Kotlin之協(xié)程(一)初識
Kotlin之協(xié)程(二)取消
簡單組合掛起函數(shù)
1.順序執(zhí)行任務(wù)
代碼如下:
private fun test() = runBlocking {
val time = measureTimeMillis {
val str1 = doIt1()
val str2 = doIt2()
Log.d(Constants.TAG, "str1->${str1},str2->${str2}")
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt1(): String {
delay(1000)
return "doIt1"
}
suspend fun doIt2(): String {
delay(1000)
return "dpIt2"
}
日志如下:
2021-09-16 16:42:51.471 28858-28858/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 16:42:51.471 28858-28858/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:2025ms
結(jié)果分析:
1贴捡、可以看到執(zhí)行結(jié)果顯示為2000+ms页滚,是兩個任務(wù)的順序執(zhí)行時長的疊加哗咆。
2.asyn進(jìn)行異步并發(fā)執(zhí)行
代碼實(shí)現(xiàn)1如下:
private fun test() = runBlocking {
val time = measureTimeMillis {
val str1 = async { doIt1() }
val str2 = doIt2()
Log.d(Constants.TAG, "str1->${str1.await()},str2->${str2}")
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt1(): String {
delay(1000)
return "doIt1"
}
suspend fun doIt2(): String {
delay(1000)
return "dpIt2"
}
日志1如下:
2021-09-16 16:46:42.394 29253-29253/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 16:46:42.394 29253-29253/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:1016ms
代碼實(shí)現(xiàn)2如下:
private fun test() = runBlocking {
val time = measureTimeMillis {
val str1 = async { doIt1() }
val str2 = async { doIt2() }
Log.d(Constants.TAG, "str1+str2->${str1.await()}+${str2.await()}")
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt1(): String {
delay(1000)
return "doIt1"
}
suspend fun doIt2(): String {
delay(1000)
return "dpIt2"
}
日志2如下:
2021-09-16 16:53:54.262 30702-30702/demo.demo.democoroutines D/Coroutines: str1+str2->doIt1+dpIt2
2021-09-16 16:53:54.263 30702-30702/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:1022ms
結(jié)果分析:
1声旺、從耗時可以看出兩個任務(wù)都進(jìn)行了并行執(zhí)行尺锚,方法1主要是將doIt1進(jìn)行了異步吼蚁,doIt2正常執(zhí)行實(shí)現(xiàn)了并行,方法2是兩個都進(jìn)行了異步辙谜。
2俺榆、方法2注意最后顯示的時候不能像方法1那樣,不然await會導(dǎo)致占用装哆,達(dá)不到理想效果(+和,隔開罐脊,"+"會同時異步執(zhí)行","則會分開)蜕琴。
3.Lazy模式的async
代碼如下:
private fun test() = runBlocking {
val time = measureTimeMillis {
val str1 = async(start = CoroutineStart.LAZY) { doIt1() }
val str2 = async(start = CoroutineStart.LAZY) { doIt2() }
str1.start()
str2.start()
Log.d(Constants.TAG, "str1->${str1.await()},str2->${str2.await()}")
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt1(): String {
delay(1000)
return "doIt1"
}
suspend fun doIt2(): String {
delay(1000)
return "dpIt2"
}
日志如下:
2021-09-16 17:08:51.066 32123-32123/demo.demo.democoroutines D/Coroutines: str1->doIt1,str2->dpIt2
2021-09-16 17:08:51.066 32123-32123/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:1017ms
結(jié)果分析:
1萍桌、從耗時可以看出也實(shí)現(xiàn)了任務(wù)的并行執(zhí)行。
4.asyn+coroutineScope實(shí)現(xiàn)結(jié)構(gòu)化
代碼1實(shí)現(xiàn)并發(fā)之并行:
private fun test() = runBlocking {
val time = measureTimeMillis {
Log.d(Constants.TAG, "str->${doIt()}")
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt(): String = coroutineScope {
val str1 = async { doIt1() }
val str2 = async { doIt2() }
str1.await() + str2.await()
}
suspend fun doIt1(): String {
delay(1000)
throw RuntimeException("doIt1出現(xiàn)異常")
return "doIt1"
}
suspend fun doIt2(): String {
delay(1000)
return "dpIt2"
}
日志1如下:
2021-09-16 17:45:01.940 3312-3312/demo.demo.democoroutines D/Coroutines: str->doIt1dpIt2
2021-09-16 17:45:01.941 3312-3312/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:1022ms
結(jié)果1分析:
1凌简、由耗時可以看出兩個任務(wù)也是一起進(jìn)行執(zhí)行的
代碼2實(shí)現(xiàn)結(jié)構(gòu)化并發(fā)之取消:
private fun test() = runBlocking {
val time = measureTimeMillis {
try {
val str = doIt()
Log.d(Constants.TAG, "str->${str}")
} catch (e: Exception) {
Log.d(Constants.TAG,"doIt出現(xiàn)異常:$e")
} finally {
Log.d(Constants.TAG,"doIt-finally")
}
}
Log.d(Constants.TAG, "共計(jì)耗時:${time}ms")
}
suspend fun doIt(): String = coroutineScope {
val str1 = async { doIt1() }
val str2 = async { doIt2() }
str1.await() + str2.await()
}
suspend fun doIt1(): String {
delay(1000)
throw RuntimeException("doIt1-執(zhí)行出現(xiàn)異常")
}
suspend fun doIt2(): String {
try {
delay(2000)
} catch (e: Exception) {
Log.d(Constants.TAG, "doIt2:$e")
} finally {
Log.d(Constants.TAG, "doIt2-finally")
}
return "dpIt2"
}
日志2如下:
2021-09-16 17:52:49.923 4299-4299/demo.demo.democoroutines D/Coroutines: doIt2:kotlinx.coroutines.JobCancellationException: Parent job is Cancelling; job=ScopeCoroutine{Cancelling}@613f107
2021-09-16 17:52:49.923 4299-4299/demo.demo.democoroutines D/Coroutines: doIt2-finally
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: doIt出現(xiàn)異常:java.lang.RuntimeException: doIt1-執(zhí)行出現(xiàn)異常
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: doIt-finally
2021-09-16 17:52:49.924 4299-4299/demo.demo.democoroutines D/Coroutines: 共計(jì)耗時:1028ms
結(jié)果2分析:
1上炎、從耗時可以看出,兩個任務(wù)在并行執(zhí)行雏搂,并且在doIt1出現(xiàn)異常之后整個doIt任務(wù)結(jié)束藕施。
2、執(zhí)行順序首先是在doIt1異常之后凸郑,doIt2被取消裳食,其次doIt打印出的異常為doIt1傳遞出的異常。
總結(jié)
本問主要介紹了組合函數(shù)的掛起及異步執(zhí)行芙沥,同時介紹了結(jié)構(gòu)化并發(fā)的實(shí)現(xiàn)以及其取消與異常傳遞诲祸,當(dāng)然這也是本人的學(xué)習(xí)筆記,希望也能對大家有那么一點(diǎn)點(diǎn)的幫助或者啟發(fā)而昨,我就很開心了救氯。當(dāng)然了本人也是在學(xué)習(xí)與理解的過程中記錄與理解難免有一定的認(rèn)知局限性,如果發(fā)現(xiàn)有什么問題配紫,歡迎指正径密,謝謝午阵。