Kotlin协程(2)基本


I.オープン模範的なコルーチン

 //全局式. 协程的生命周期只受整个应用程序的生命周期的限制。
 GlobalScope.launch(Dispatchers.Unconfined) {
     println("hello, (${Thread.currentThread().name})")
     delay(1000L)
     println("stone")
 }
 // GlobalScope.async { }

//阻塞式
runBlocking {
    delay(1000L) //与上一个delay基本是同时执行的,只晚一点点。
    println("Did you win the lottery?")
}

//阻塞式 返回 T
val v = runBlocking {
    delay(1500L)
    GlobalScope.launch {
        println("yeah. $2")
    }
    delay(500)
    "i win"
}
println(v)

私は。launch()あるCoroutineScope拡張機能

ソースコードを参照してください、

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
}

私たちは、内部構築するcoroutineインスタンスとの通話をstart()コルーチンを開始します。戻りJobインスタンス。

II。async()またCoroutineScope、拡張機能

私たちは、内部構築するcoroutineインスタンスとの通話をstart()コルーチンを開始します。戻りDeferredインスタンス。
関数名を見て、非同期の意味であるが、それは、非同期スレッドで実行必ずしも意味するものではありません。しかし、その機能はすぐに実行されないことがあります。

III。runBlocking()機能です

@Throws(InterruptedException::class)
public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
    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()
}

私たちは、内部構築するcoroutineインスタンスとの通話をstart()コルーチンを開始します。戻り値が渡されblock()、最後の行に。したがって、サンプル・コードが出力されますi win
このブロッキングが達成され、すなわち、同期、非同期の非実装であることが理解されるであろう。呼び出し側は、スレッドをブロックしています。

コンソールプログラムは、非ブロッキング遅延コルーチンで使用される場合()メイン関数main()は完成実行を有し、その後の動作を見ることができないかもしれません。だから、()メインとして宣言することができます:fun main() = runBlocking { ... }


II。Kotlinxは、ライブラリコルーチンCoroutineScope系譜を

私は。系譜

CoroutineScopeファミリーツリー
フィギュアのベースとコルーチンライブラリが1.3.5(非アンドリュース上)kotlin.coroutines CoroutineScope系譜を。

public interface CoroutineScope {
    public val coroutineContext: CoroutineContext
}

ソースコードを参照してくださいCoroutineScope定数の定義内で定義しcoroutineContext、実際にそれが抽象的です、。カスタムのようにCoroutineScope

class MyContextScope(override val coroutineContext: CoroutineContext) : CoroutineScope {

}

図は、結合、それはこれらの内部のSDK達成するために、理解されるXxxCoroutineコルーチンを、実際に達成しましたCoroutineScope
彼らは、割り当てプロセスをcoroutineContextます。

II。サスペンド機能 coroutineScope()

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

SDKの機能、保留中の機能である、内部作成coroutineコルーチン例を。
その機能が中断され、それが1または別のコルーチン関数呼び出しを中断で置換されていなければなりません。

fun main(args: Array<String>) = runBlocking {
	coroutineScope {
        launch {
            delay(500L)
            println("Task from nested launch")
        }
        delay(100L)
        println("Task from coroutine scope") // This line will be printed before the nested launch
    }
}

III。JobDeferred

I。Jobはじめに

launch()リターンJob実装し、CoroutineContextインタフェースが、内部は3つの属性があります。

public val isActive: Boolean
public val isCompleted: Boolean
public val isCancelled: Boolean

ドキュメンテーションコメントは、以下の簡単な概略フロー図、上述した3つの特性の効果があります。

                                    wait children
+-----+ start  +--------+ complete   +-------------+  finish  +-----------+
| New | -----> | Active | ---------> | Completing  | -------> | Completed |
+-----+        +--------+            +-------------+          +-----------+
               |  cancel / fail       |
               |     +----------------+
               |     |
               V     V
           +------------+                           finish  +-----------+
           | Cancelling | --------------------------------> | Cancelled |
           +------------+                                   +-----------+

新規ジョブのインスタンスは、アクティブ状態に入るために開始し、
アクティブ状態は、あなたが、終了後のキャンセル、キャンセルキャンセル状況を入力することができ、
アクティブ状態、実行が正常に完了(サブジョブがある場合は、すべての子供のための待機ジョブが完了実行を自体を完了またはサブジョブの実行をキャンセル又はエラーが発生していない場合は、キャンセル状態に入る;)、完了状態に入ります。

II。Job重要cancel()な機能:join()、、cancelAndJoin

例えば、Aの

val job = GlobalScope.launch {
   delay(1000L)
   launch {
       delay(8000)
       println(8/0)
   }
    println("World!")
}
job.cancel()
println("Hello,")
//    job.join() // wait until child coroutine completes
println("unprecedented ${job.isCompleted}")
println("unprecedented ${job.isCancelled}")

cancel()ジョブをキャンセルし、実際には、キャンセルGlobalScope.launch{}全体コルーチンタスクを。(他のコードの前に遅延(1000)は、まだ実行されます。) job.isCompleted 值是 falsejob.isCancelled 值是 true

開いjob.join()た後job.isCompleted 值是 true、コメントjob.isCancelled 值是 true、。join()すべての子が完了しているのを待っているので、後で、それはですisCompleted 是 true

cancelAndJoin()内部実装は、最初に呼び出されcancel()た後、コールjoin()

()キャンセルの場合は、呼び出しはすぐにキャンセルされますされていません。これは、正常にキャンセルするためには、「一時停止」操作に直面して、ドライブを共同ます。

III。JobサブクラスのDeferred
async()復帰は延期します。これは、1つの以上の重要な方法ですawait()

 // 挂起函数中,调用其它挂起函数;挂起协程
suspend fun doWorld() {
    delay(1000L)
    println("World!")
    repeat(10) { i ->
        print("${i}\t")
    }
    println()
}
//协程中 调用挂起函数
val deferred1 = async {
    doWorld()
    "done ${Thread.currentThread().name}"
}
println(deferred1.await())

val deferred2 = async(start = CoroutineStart.LAZY) {
    println("时间:${System.currentTimeMillis()}")
    "done ${Thread.currentThread().name}"
}
delay(3000)
println(deferred2.await())

async()デフォルトでは、次のような、すぐに実行されますval r = async {...}呼び出しは、deferred1.await()結果を得ることができます。
val deferred2 = async(start = CoroutineStart.LAZY) {...}スタートは怠け者である場合には、コルーチン呼び出しがしますdeferred2.await()時に始まります。


IV。まとめ

コルーチンを開く方法:

GlobalScopeグローバル、内部スレッドプール、オプションの打ち上げ()、非同期()
非グローバル、およびデフォルトは、呼び出し側のスレッドで実行することで、非同期スレッドCoroutineContextパラメータを指定したと関連付けられていません。
繰延打ち上げ()戻り仕事、非同期()を返します。動作選択するかどうか戻り値。
runBlocking()ブロックには、戻り値、単位のさえ空のタイプを必要とすることが、呼び出し元のスレッドに注意してください。
非グローバルコ離れ作成する機能coroutineScope()を中断します。


V.リファレンス

基本コルーチン
Kotlinコルーチンライブラリ


公開された400元の記事 ウォンの賞賛364 ビュー162万+

おすすめ

転載: blog.csdn.net/jjwwmlp456/article/details/105194794