Kotlin協程的啟動方式介紹
啟動協程的基本方式
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函數是CoroutineScope的擴展函數,它有三個參數:
- context: CoroutineContext = EmptyCoroutineContext, 第一個參數是協程上下文,它的默認值是 EmptyCoroutineContext,如果不傳這個參數,默認就會使用 EmptyCoroutineContext。也可以傳入 Kotlin 官方為我們提供的 Dispatchers,來指定協程運行的線程池。(Dispatchers.IO、Dispatchers.Unconfined、Dispatchers.Main)
- start: CoroutineStart = CoroutineStart.DEFAULT,第二個參數是協程的啟動模式,默認值是CoroutineStart.DEFAULT,CoroutineStart 是一個枚舉類,一共有:DEFAULT、LAZY、ATOMIC、UNDISPATCHED。
- block: suspend CoroutineScope.() -> Unit,第三個參數是函數類型block,它的類型是suspend CoroutineScope.() -> Unit。本質是一個掛起函數。
- 函數的返回值是一個 Job,它其實代表的是協程的句柄,並不能返回協程的執行結果。
2.runBlocking 啟動協程
代碼示例
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是普通函數,第一個參數:context: CoroutineContext,協程上下文。第二個參數是函數類型,block: suspend CoroutineScope.() -> T,函數類型是有返回值類型 T 的,與 runBlocking 的返回值類型是一樣的,runBlocking 其實是可以從協程當中返回執行結果的。
fun testRunBlocking() { val runBlockingResult = runBlocking { delay(500L) return@runBlocking "HaHa" } println("result:$runBlockingResult") } result:HaHa
runBlocking特點:
runBlocking 啟動的協程會阻塞當前線程的執行。
3.async啟動協程
使用 async{} 創建協程,可以通過它返回的Deferred拿到協程的執行結果。
代碼示例
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 啟動協程以後,不會阻塞當前程序的執行流程。
- async{}的返回值,是一個 Deferred 對象,它的 await() 方法,就可以拿到協程的執行結果。
- await隻是等待執行完,並不是觸發執行。
到此這篇關於Kotlin協程的啟動方式介紹的文章就介紹到這瞭,更多相關Kotlin協程啟動內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Kotlin協程launch原理詳解
- Kotlin協程到底是如何切換線程的
- Kotlin線程的橋接與切換使用介紹
- Kotlin協程launch啟動流程原理詳解
- Kotlin協程Job生命周期結構化並發詳解