亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

kotlin協(xié)程之coroutineScope函數(shù)使用詳解

 更新時(shí)間:2022年09月08日 14:44:24   作者:最?lèi)?ài)大頭貓  
這篇文章主要為大家介紹了kotlin協(xié)程之coroutineScope函數(shù)使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return suspendCoroutineUninterceptedOrReturn { uCont ->
        val coroutine = ScopeCoroutine(uCont.context, uCont, true)
        coroutine.startUndispatchedOrReturn(coroutine, block)
    }
}

它是一個(gè)suspend函數(shù),創(chuàng)建一個(gè)新的協(xié)程作用域,并在該作用域內(nèi)執(zhí)行指定代碼塊,它并不啟動(dòng)協(xié)程。其存在的目的是進(jìn)行符合結(jié)構(gòu)化并發(fā)的并行分解(即,將長(zhǎng)耗時(shí)任務(wù)拆分為并發(fā)的多個(gè)短耗時(shí)任務(wù),并等待所有并發(fā)任務(wù)完成后再返回)。

coroutineScoperunBlocking的區(qū)別在于runBlocking會(huì)阻塞當(dāng)前線程,而coroutineScope會(huì)掛起所在的協(xié)程直至其內(nèi)部任務(wù)(包括子協(xié)程)執(zhí)行完成,它不會(huì)阻塞所在的線程。

coroutineScope是一個(gè)掛起函數(shù),它被掛起后,會(huì)轉(zhuǎn)而執(zhí)行之前的子協(xié)程。

fun main() = runBlocking {
    launch {        //launch①       
        delay(1000)                 //掛起launch①
        println("test2")
    }
    println("test1")
    coroutineScope {                //第一次掛起runBlocking,直至內(nèi)部邏輯完成
        launch {    //launch②
            delay(2000)             //掛起launch②
            println("test3")
        }
        delay(5000)     //delay①    //第二次掛起runBlocking
        println("test4")
    }
    println("test5")
}
//test1
//test2
//test3
//test4
//test5

代碼分析

  • runBlockingmain線程創(chuàng)建并啟動(dòng)一個(gè)阻塞的協(xié)程;
  • 創(chuàng)建launch①子協(xié)程,由于創(chuàng)建協(xié)程是需要一些時(shí)間的,并且協(xié)程的創(chuàng)建是由特定的線程來(lái)完成,并非是main線程。所以在創(chuàng)建協(xié)程過(guò)程中會(huì)并行地執(zhí)行后續(xù)代碼。因此test1被輸出。
  • 執(zhí)行到coroutineScope函數(shù)時(shí),把runBlocking掛起,直到內(nèi)部邏輯執(zhí)行完成。
  • 然后創(chuàng)建launch②協(xié)程,創(chuàng)建過(guò)程中執(zhí)行執(zhí)行后續(xù)代碼:delay①繼續(xù)掛起runBlocking5s(掛起函數(shù)中調(diào)用掛起函數(shù))。
  • 等到launch①創(chuàng)建完畢時(shí),把它掛起1s。launch②創(chuàng)建完畢時(shí),把它掛起2s。
  • 此時(shí)runBlocking、launch①、launch②都是被掛起狀態(tài)。
  • 等到1s后launch①恢復(fù),輸出test2;2s后launch②被恢復(fù),輸出test3;5s后runBlocking第二次掛起被恢復(fù),輸出test4。
  • 此時(shí)coroutineScope中的邏輯已經(jīng)執(zhí)行完成,恢復(fù)runBlocking的第一次掛起,test5被輸出。

這比較難以理解,下面的案例稍微容易些:

fun main() = runBlocking {
    launch {
        println("test3")
    }
    println("test1")
    coroutineScope {    //掛起runBlocking,直到內(nèi)部邏輯完成
        println("test2")
        delay(1000)     //掛起runBlocking5s
        println("test4")
    }
    println("test5")    //必須等待掛起函數(shù)coroutineScope執(zhí)行完畢后才會(huì)被執(zhí)行
}
//test1
//test2
//test3
//test4
//test5

而如果把coroutineScope函數(shù)改成delay函數(shù),會(huì)更加容易理解,因?yàn)樗鼈兌际菕炱鸷瘮?shù)。

fun main() = runBlocking {
    launch {
        delay(1000)
        println("test2")
    }
    println("test1")
    delay(2000)     //掛起runBlocking協(xié)程2s
    println("test3")
}
//test1
//test2
//test3

coroutineScope經(jīng)常用來(lái)把一個(gè)長(zhǎng)耗時(shí)的任務(wù)拆分成多個(gè)子任務(wù),使這些子任務(wù)并行執(zhí)行

suspend fun showSomeData() = coroutineScope {
    val data1 = async {         //子任務(wù)1
        delay(2000)
        100
    }
    val data2 = async {         //子任務(wù)2
        delay(3000)
        20
    }
    withContext(Dispatchers.Default) {      //合并結(jié)果并返回
        delay(3000)
        val random = Random(10)
        data1.await() + data2.await() + random.nextInt(100)
    }
}

coroutineScope有如下語(yǔ)義:

  • 并行執(zhí)行內(nèi)部任務(wù)data1、data2withContext
  • 如果其它任務(wù)(random)拋出異常,data1data2兩個(gè)任務(wù)會(huì)被取消
  • 如果showSomeData()被取消,內(nèi)部的data1、data2withContext都會(huì)被取消
  • 如果data1、data2失敗,withContext被取消。

以上就是kotlin協(xié)程之coroutineScope函數(shù)使用詳解的詳細(xì)內(nèi)容,更多關(guān)于kotlin協(xié)程coroutineScope函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論