Kotlin coroutine concurrency/parallel and serial switching, CoroutineScope and await

Kotlin coroutine concurrency/parallel and serial switching, CoroutineScope and await

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    CoroutineScope(Dispatchers. Default). launch {
        // execute concurrently
        this. launch {
            println("${LocalTime.now()} A start")
            delay(1000)
            println("${LocalTime.now()} A end")
        }

        this. launch {
            println("${LocalTime.now()} B start")
            delay(1500)
            println("${LocalTime.now()} B end")
        }
    }

    println("${LocalTime.now()} - main end")
}

87f9d76084ad4426bafefd397bbdf68a.png

The output shows that after main exits, A and B have no output. CoroutineScope(Dispatchers.IO).launch The new task does not block the execution process of the main main task.

If you change to runBlocking(Dispatchers.IO):

import kotlinx.coroutines.*
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    runBlocking(Dispatchers.IO) {
        // execute concurrently
        this. launch {
            println("${LocalTime.now()} A start")
            delay(1000)
            println("${LocalTime.now()} A end")
        }

        this. launch {
            println("${LocalTime.now()} B start")
            delay(1500)
            println("${LocalTime.now()} B end")
        }
    }

    println("${LocalTime.now()} - main end")
}

1f6b5f0d021045d7893676b304f93a40.png

look at async

import kotlinx.coroutines.*
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    CoroutineScope(Dispatchers.IO). launch() {
        // execute concurrently
        this. async {
            println("${LocalTime.now()} A start")
            delay(1000)
            println("${LocalTime.now()} A end")
        }

        this. async {
            println("${LocalTime.now()} B start")
            delay(1500)
            println("${LocalTime.now()} B end")
        }
    }

    println("${LocalTime.now()} - main end")
}

b2bbb1a5826f4435b74dd643b3b9eabc.png

If the main thread rests for 1000ms:

import kotlinx.coroutines.*
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    CoroutineScope(Dispatchers.IO). launch() {
        // execute concurrently
        this. async {
            println("${LocalTime.now()} A start")
            delay(1000)
            println("${LocalTime.now()} A end")
        }

        this. async {
            println("${LocalTime.now()} B start")
            delay(1500)
            println("${LocalTime.now()} B end")
        }
    }

    Thread. sleep(1000)
    println("${LocalTime.now()} - main end")
}

bc1857a373b2488da03f53447e70202b.png

import kotlinx.coroutines.*
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    runBlocking {
        CoroutineScope(Dispatchers.IO). launch() {
            val task1 = this. async {
                println("${LocalTime.now()} A start")
                delay(1000)
                println("${LocalTime.now()} A end")

                "task1 return"
            }

            val task2 = this. async {
                println("${LocalTime.now()} B start")
                delay(1500)
                println("${LocalTime.now()} B end")

                "task2 return"
            }

            val t1 = task1. await()
            println("${LocalTime.now()} $t1")

            val t2 = task2. await()
            println("${LocalTime.now()} $t2")
        }
    }

    println("${LocalTime.now()} - main end")
}

39e1e4a2e3e3478da0ef690db39afe19.png

In general, the significance of CoroutineScope(Dispatchers.IO).launch() is to start a new thread without blocking the main main thread, because

understand await

import kotlinx.coroutines.*
import java.time.LocalTime

fun main(args: Array<String>) {
    println("${LocalTime.now()} - main start")

    runBlocking {
        //launch() {
            val task1 = this. async {
                println("${LocalTime.now()} A start")
                delay(3000)
                println("${LocalTime.now()} A end")

                "task1 return"
            }

            val task2 = this. async {
                println("${LocalTime.now()} B start")
                delay(1000)
                println("${LocalTime.now()} B end")

                "task2 return"
            }

            val t1 = task1. await()
            println("${LocalTime.now()} $t1")

            val t2 = task2. await()
            println("${LocalTime.now()} $t2")
        //}
    }

    println("${LocalTime.now()} - main end")
}

1ec6b998a72b411fab336c7ce142b909.png

Although task2 is completed soon, because of await, it must wait for task1 to return.

The kotlin coroutine async and await_zhangphil’s blog-CSDN blog runBlocking internally starts 3 coroutines to do time-consuming operations. From the output, you can see that the 3 coroutines are executed concurrently. RunBlocking will wait until the execution of the 3 coroutines is completed before exiting. The output results have a clear sequence. General programming techniques, for example, in Android, suppose a function is implemented in the main thread, but this function is a time-consuming operation, there is no doubt that the implementation of this function needs to be cut into a non-main thread for operation, then you can design a A managed function that does dirty work in the managed function, and throws the result to the main thread after the processing is completed. Result 1-a: 5 – tid: 22. Result 1-b: 5 – tid: 24. Result 2-a: 9 – tid: 22. https:/ /blog.csdn.net/zhangphil/article/details/129268399

https://zhangphil.blog.csdn.net/article/details/129265638https://zhangphil.blog.csdn.net/article/details/129265638

Kotlin coroutines, thread switching, function method entrustment_zhangphil’s blog-CSDN blog runBlocking internally starts 3 coroutines to do time-consuming operations, you can see from the output that 3 coroutines are cross-concurrently executed, and runBlocking will wait until 3 coroutines Exit after the execution is completed, and the output results have a clear sequence. General programming techniques, for example, in Android, suppose a function is implemented in the main thread, but this function is a time-consuming operation, there is no doubt that the implementation of this function needs to be cut into a non-main thread for operation, then you can design a A managed function that does dirty work in the managed function, and throws the result to the main thread after the processing is completed. Result 1-a: 5 – tid: 22. Result 1-b: 5 – tid: 24. Result 2-a: 9 – tid: 22. https:/ /blog.csdn.net/zhangphil/article/details/130161705

https://zhangphil.blog.csdn.net/article/details/129250518https://zhangphil.blog.csdn.net/article/details/129250518