第四章.関数とサブルーチンコンテキストの一時停止


保留関数
  • suspendコントロールを追加するだけです.
  • は、遅延()
  • のような一時停止関数を直接呼び出す.
  • は、他の一時停止演算でのみ呼び出す
  • である.
    fun main(args : Array<String>){
    	runBlocking{
        	greetDelayed(1000)
        }
    }
    
    suspend fun greetDelayed(delayMillis : Long){
    	delay(delayMillis)
        println("Hello, world!")
    }
    非一時停止コードで関数を呼び出すにはcoutinコンストラクタを使用してカプセル化する必要があります.
    Dispatcher(Dispatcher)
  • スレッドが実行されるスレッドを決定します.
  • は、起動点および停止後の復帰点
  • を含む.
    Unconfined
  • 現在のスレッドは
  • を実行し、第1のブレークポイントに達するまで実行します.
  • が一時停止すると、一時停止計算で使用する既存スレッドから
  • が再起動する.
    fun main(args : Array<String>) : Unit = runBlocking{
        GlobalScope.launch(Dispatchers.Unconfined) {
            println("Starting in ${Thread.currentThread().name}")
            delay(1000L)
            println("Resuming in ${Thread.currentThread().name}")
        }.join()
    }
    中断する前にmainで実行し、DefaultExecutorで実行できます.
    シングルスレッド集約
  • スレッドは常に特定のスレッドで実行されます.
  • newSingleThreadContext()を使用してDispatcher
  • を生成
    fun main(args : Array<String>) : Unit = runBlocking{
        val dispatcher = newSingleThreadContext(name = "myThread")
    
        GlobalScope.launch(dispatcher){
            println("Starting in ${Thread.currentThread().name}")
            delay(500L)
            println("Resuming in ${Thread.currentThread().name}")
        }.join()
    }
    スレッド(myThread)で実行を続行できることを確認します.
    スレッドプール
  • は、このプールで使用可能なスレッドでスレッドを起動、復元します.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val dispatcherPool = newFixedThreadPoolContext(4,"myPool")
    
        GlobalScope.launch(dispatcherPool) {
            println("Staring in ${Thread.currentThread().name}")
            delay(500L)
            println("Resuming in ${Thread.currentThread().name}")
        }.join()
    }
    例外処理
  • DispatchだけでなくHandlerも加わって異常処理が可能です.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val handler = CoroutineExceptionHandler { context, throwable ->
            println("Error captured in $context")
            println("Message: ${throwable.message}")
        }
    
        GlobalScope.launch(handler) {
            TODO("Not implemented yet!")
        }
    
        delay(500L)
    }
    Non-cancellable
  • をキャンセルしているコルディンは、一時停止できないように設計されています.
  • 鼻ルーチンをキャンセルする間、NonCancelableコンテキストを使用して一時停止する必要があります.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val duration = measureTimeMillis {
            val job = launch {
                try{
                    while(isActive){
                        delay(500L)
                        println("still running")
                    }
                }finally {
                    withContext(NonCancellable) {
                        println("cancelled, will end now")
                        delay(5000L)
                        println("delay completed, bye bye")
                    }
    
                }
            }
            delay(1200L)
            job.cancelAndJoin()
        }
    
        println("Took $duration ms")
    }
    コンテキストに関するコメント
    コンテキストの組合せ
    連結は、
  • プラス記号演算子で行うことができます.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val dispatcher = newSingleThreadContext("myThread")
        val handler = CoroutineExceptionHandler { context, throwable ->
            println("Error captured")
            println("Message: ${throwable.message}")
        }
    
        GlobalScope.launch(dispatcher + handler) {
            println("Running in ${Thread.currentThread().name}")
            TODO("Not implemented")
        }.join()
    }
    コンテキストの分離
  • minusKey()を使用してコンテキスト要素を削除できます.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val dispatcher = newSingleThreadContext("myThread")
        val handler = CoroutineExceptionHandler { context, throwable ->
            println("Error captured")
            println("Message: ${throwable.message}")
        }
    
        val context = dispatcher + handler
        val tmpCtx = context.minusKey(dispatcher.key)
    
        GlobalScope.launch(tmpCtx) {
            println("Running in ${Thread.currentThread().name}")
            TODO("Not implemented")
        }.join()
    }
    myThreadではなくDefaultスレッドを確認できます.
    withContext
  • コードブロックの所与のコンテキストを実行するための一時停止関数.
  • withContext()関数が返す値は、伝達されたramdaの最後の構文に対応し、JobまたはDeferredを返さない.
  • fun main(args : Array<String>) : Unit = runBlocking{
        val dispatcher = newSingleThreadContext("myThread")
        val name = GlobalScope.async(dispatcher) {
            "Susan Calvin"
        }.await()
    
        println("User $name")
    
        val name1= withContext(dispatcher){
            "Susan Calvin"
        }
        println("User1 $name1")
    }
    同じSusan Calvinの結果値を表示できます.
    リファレンス
  • learning Concurrency in Kotlin