點(diǎn)擊查看CoroutineStart英文文檔
創(chuàng)建協(xié)程的三種方式
- runBlocking
運(yùn)行一個(gè)協(xié)程并且會(huì)阻塞當(dāng)前線程,直到它完成。- launch
啟動(dòng)一個(gè)新的協(xié)程,不會(huì)阻塞當(dāng)前線程,并且返回一個(gè)Job,可以取消。- async
async和await是兩個(gè)函數(shù),這兩個(gè)函數(shù)在我們使用過(guò)程中一般都是成對(duì)出現(xiàn)的。
async用于啟動(dòng)一個(gè)異步的協(xié)程任務(wù),await用于去得到協(xié)程任務(wù)結(jié)束時(shí)返回的結(jié)果,結(jié)果是通過(guò)一個(gè)Deferred對(duì)象返回的。
在概念上,async 就類似于 launch。它啟動(dòng)了一個(gè)單獨(dú)的協(xié)程,這是一個(gè)輕量級(jí)的線程并與其它所有的協(xié)程一起并發(fā)的工作。不同之處在于 launch 返回一個(gè) Job 并且不附帶任何結(jié)果值,而 async 返回一個(gè) Deferred —— 一個(gè)輕量級(jí)的非阻塞 future, 這代表了一個(gè)將會(huì)在稍后提供結(jié)果的 promise。可以使用 .await() 在一個(gè)延期的值上得到它的最終結(jié)果, 但是 Deferred 也是一個(gè) Job,所以如果需要的話,你可以取消它。
CoroutineStart源碼
協(xié)程的四種啟動(dòng)模式一:DEFAULT
Default——根據(jù)上下文立即調(diào)度協(xié)程執(zhí)行。
如果協(xié)程上下文的[CoroutineDispatcher]從[CoroutineDispatcher. isdispatchneeded]返回’ true ’
函數(shù),然后協(xié)程代碼被調(diào)度以供稍后執(zhí)行,而代碼被調(diào)度
被調(diào)用的協(xié)程構(gòu)建器繼續(xù)執(zhí)行。
注意[Dispatchers。unconstrained總是從它的[CoroutineDispatcher.isDispatchNeeded]返回false
函數(shù),所以用[Dispatchers. *]啟動(dòng)協(xié)程。unconstrained [DEFAULT]與使用[un分派]相同。
如果協(xié)程[Job]在它有機(jī)會(huì)開(kāi)始執(zhí)行之前被取消,那么它將不會(huì)啟動(dòng)它的執(zhí)行,但將以異常完成。
在掛起點(diǎn)的協(xié)同程序的可取消性取決于的具體實(shí)現(xiàn)細(xì)節(jié)暫停功能。使用[suspenpendcancellablecoroutine]實(shí)現(xiàn)可取消的掛起函數(shù)。
示例
fun main() = runBlocking {
val job = launch (start = CoroutineStart.DEFAULT){
println("開(kāi)始執(zhí)行耗時(shí)操作...")
delay(2000L)
println("耗時(shí)操作結(jié)束")
}
delay(1000L)
job.cancel()
println("任務(wù)取消了")
}
運(yùn)行結(jié)果
協(xié)程的四種啟動(dòng)模式二:LAZY
僅在需要時(shí)才惰性地啟動(dòng)協(xié)程。
詳細(xì)信息請(qǐng)參見(jiàn)相應(yīng)協(xié)程構(gòu)建器的文檔
(如[launch][CoroutineScope])。launch]和[async][coroutincope .async])。
如果協(xié)程[Job]在它有機(jī)會(huì)開(kāi)始執(zhí)行之前被取消,那么它將不會(huì)啟動(dòng)它的執(zhí)行,但將以異常完成。
fun main() = runBlocking {
val job = async (start = CoroutineStart.LAZY){
println("開(kāi)始執(zhí)行耗時(shí)操作...")
delay(2000L)
println("耗時(shí)操作結(jié)束")
}
delay(1000L)
job.cancel()
println("任務(wù)取消了")
job.await()
}
運(yùn)行結(jié)果
協(xié)程的四種啟動(dòng)模式三:ATOMIC
自動(dòng)地(即,以一種不可取消的方式)根據(jù)上下文調(diào)度協(xié)程的執(zhí)行。
這類似于[DEFAULT],但是協(xié)程在開(kāi)始執(zhí)行之前不能被取消。
在掛起點(diǎn)的協(xié)程是否可取消,取決于掛起函數(shù)如[DEFAULT]。
@ExperimentalCoroutinesApi //從1.0.0開(kāi)始,沒(méi)有穩(wěn)定性的ETA
fun main() = runBlocking {
val job = async(start = CoroutineStart.ATOMIC) {
println("開(kāi)始執(zhí)行耗時(shí)操作...")
//在掛起點(diǎn)之前不會(huì)被取消
delay(2000L)//這里就是一個(gè)掛起點(diǎn), delay是掛起函數(shù)
println("耗時(shí)操作結(jié)束")
}
delay(1000L)
job.cancel()
println("任務(wù)取消了")
}
運(yùn)行結(jié)果
協(xié)程的四種啟動(dòng)模式四:UNDISPATCHED
立即執(zhí)行協(xié)程,直到它在當(dāng)前線程中的第一個(gè)掛起點(diǎn)
協(xié)程是使用[dispatchers . unconstrained]啟動(dòng)的。但是,當(dāng)協(xié)程從暫停狀態(tài)恢復(fù)時(shí)
根據(jù)上下文中的[CoroutineDispatcher]進(jìn)行分派。
這類似于[ATOMIC],因?yàn)閰f(xié)程即使已經(jīng)被取消也會(huì)開(kāi)始執(zhí)行。
但不同之處在于它在同一個(gè)線程中開(kāi)始執(zhí)行。
在掛起點(diǎn)的協(xié)程是否可取消,取決于掛起函數(shù)如[DEFAULT]。
注:這是一個(gè)實(shí)驗(yàn)性api。當(dāng)使用此模式時(shí),協(xié)程的執(zhí)行語(yǔ)義可能會(huì)在將來(lái)發(fā)生變化。
@ExperimentalCoroutinesApi //從1.0.0開(kāi)始,沒(méi)有穩(wěn)定性的ETA
fun main() = runBlocking {
val job = async(context = Dispatchers.IO, start = CoroutineStart.UNDISPATCHED) {
println("開(kāi)始執(zhí)行耗時(shí)操作... ${Thread.currentThread().name}")
//在掛起點(diǎn)之前不會(huì)被取消
delay(2000L)//這里就是一個(gè)掛起點(diǎn), delay是掛起函數(shù)
println("耗時(shí)操作結(jié)束...${Thread.currentThread().name}")
}
delay(1000L)
job.cancel()
println("任務(wù)取消了...${Thread.currentThread().name}")
}
運(yùn)行結(jié)果
從上圖可以看到, async(context = Dispatchers.IO, start = CoroutineStart.UNDISPATCHED) ,但是還在主線程執(zhí)行的。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-856249.html
推薦
Kotlin:組合掛起函數(shù)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-856249.html
到了這里,關(guān)于Kotlin: 協(xié)程的四種啟動(dòng)模式(CoroutineStart)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!