欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

正文

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)
    }
}

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

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

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

而如果把coroutineScope函數(shù)改成delay函數(shù),會更加容易理解,因為它們都是掛起函數(shù)。

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

coroutineScope經(jīng)常用來把一個長耗時的任務拆分成多個子任務,使這些子任務并行執(zhí)行

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

coroutineScope有如下語義:

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

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

相關文章

最新評論