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

Kotlin協(xié)程的啟動方式介紹

 更新時間:2022年09月07日 14:56:34   作者:且聽真言  
這篇文章我們來講協(xié)程的啟動,畢竟協(xié)程是一個很強大的設(shè)計模式,深入了解需要花很多的時間,我們先從簡單開始,其實學(xué)會了簡單的使用,基本已經(jīng)可以滿足我們平時的開發(fā)需要了,話不多說,開始

啟動協(xié)程的基本方式

1.GlobalScope.launch

代碼示例:

fun testGlobalScope() {
    GlobalScope.launch {
        println("Coroutinue started!")
        delay(1000L)
        println("Hello World!")
    }
    println("After launch!")
    Thread.sleep(2000L)
    println("Process end!")
}
/**
 * After launch!
 * Coroutinue started!
 * Hello World!
 * Process end!
 */
@DelicateCoroutinesApi
public object GlobalScope : CoroutineScope {
    /**
     * Returns [EmptyCoroutineContext].
     */
    override val coroutineContext: CoroutineContext
        get() = EmptyCoroutineContext
}
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

launch函數(shù)是CoroutineScope的擴展函數(shù),它有三個參數(shù):

  • context: CoroutineContext = EmptyCoroutineContext, 第一個參數(shù)是協(xié)程上下文,它的默認(rèn)值是 EmptyCoroutineContext,如果不傳這個參數(shù),默認(rèn)就會使用 EmptyCoroutineContext。也可以傳入 Kotlin 官方為我們提供的 Dispatchers,來指定協(xié)程運行的線程池。(Dispatchers.IO、Dispatchers.Unconfined、Dispatchers.Main)
  • start: CoroutineStart = CoroutineStart.DEFAULT,第二個參數(shù)是協(xié)程的啟動模式,默認(rèn)值是CoroutineStart.DEFAULT,CoroutineStart 是一個枚舉類,一共有:DEFAULT、LAZY、ATOMIC、UNDISPATCHED。
  • block: suspend CoroutineScope.() -> Unit,第三個參數(shù)是函數(shù)類型block,它的類型是suspend CoroutineScope.() -> Unit。本質(zhì)是一個掛起函數(shù)。
  • 函數(shù)的返回值是一個 Job,它其實代表的是協(xié)程的句柄,并不能返回協(xié)程的執(zhí)行結(jié)果。

2.runBlocking 啟動協(xié)程

代碼示例

fun testRunBlocking2() {
    runBlocking {
        println("Coroutinue started!")
        delay(1000L)
        println("Hello World!")
    }
    println("After Launch")
    Thread.sleep(2000L)
    println("Process end")
}
/**
 * Coroutinue started!
 * Hello World!
 * After Launch
 * Process end
 */
@Throws(InterruptedException::class)
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    val currentThread = Thread.currentThread()
    val contextInterceptor = context[ContinuationInterceptor]
    val eventLoop: EventLoop?
    val newContext: CoroutineContext
    if (contextInterceptor == null) {
        // create or use private event loop if no dispatcher is specified
        eventLoop = ThreadLocalEventLoop.eventLoop
        newContext = GlobalScope.newCoroutineContext(context + eventLoop)
    } else {
        // See if context's interceptor is an event loop that we shall use (to support TestContext)
        // or take an existing thread-local event loop if present to avoid blocking it (but don't create one)
        eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() }
            ?: ThreadLocalEventLoop.currentOrNull()
        newContext = GlobalScope.newCoroutineContext(context)
    }
    val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
    coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
    return coroutine.joinBlocking()
}

runBlocking是普通函數(shù),第一個參數(shù):context: CoroutineContext,協(xié)程上下文。第二個參數(shù)是函數(shù)類型,block: suspend CoroutineScope.() -> T,函數(shù)類型是有返回值類型 T 的,與 runBlocking 的返回值類型是一樣的,runBlocking 其實是可以從協(xié)程當(dāng)中返回執(zhí)行結(jié)果的。

fun testRunBlocking() {
    val runBlockingResult = runBlocking {
        delay(500L)
        return@runBlocking "HaHa"
    }
    println("result:$runBlockingResult")
}
result:HaHa

runBlocking特點:

runBlocking 啟動的協(xié)程會阻塞當(dāng)前線程的執(zhí)行。

3.async啟動協(xié)程

使用 async{} 創(chuàng)建協(xié)程,可以通過它返回的Deferred拿到協(xié)程的執(zhí)行結(jié)果。

代碼示例

fun testAsync() {
    runBlocking {
        val deferred = async {
            println("do async:${Thread.currentThread().name}")
            delay(1000L)
            return@async "do completed"
        }
        println("After async:${Thread.currentThread().name}")
        val result = deferred.await()
        println("Result is: $result")
    }
}
After async:main @coroutine#1
do async:main @coroutine#2
Result is: do completed
public fun <T> CoroutineScope.async(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> T
): Deferred<T> {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
        LazyDeferredCoroutine(newContext, block) else
        DeferredCoroutine<T>(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}

async注意點

  • async 啟動協(xié)程以后,不會阻塞當(dāng)前程序的執(zhí)行流程。
  • async{}的返回值,是一個 Deferred 對象,它的 await() 方法,就可以拿到協(xié)程的執(zhí)行結(jié)果。
  • await只是等待執(zhí)行完,并不是觸發(fā)執(zhí)行。

到此這篇關(guān)于Kotlin協(xié)程的啟動方式介紹的文章就介紹到這了,更多相關(guān)Kotlin協(xié)程啟動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論