First, coroutines are lightweight threads

How coroutines are created

1.GlobalScope.launch

GlobalScope.launch(Dispatchers.Main) {
    println("")}Copy the code

This function creates the scope of a coroutine in which the Lambda expression is run. This function creates a top-level coroutine that terminates when the program runs. You’ll notice that the log does not print after execution because the program ends before it can execute the code in the block.

2.delay

GlobalScope.launch{
    println("")
    delay(1000)}Copy the code

I’m just going to add a delay, and the delay is a non-blocking suspend function, and the delay will suspend the current coroutine, but it won’t affect any other coroutines, and I’m sure you’re thinking of Thread sleep, but Thread sleep blocks the current Thread, All coroutines under this thread will also block.

3.runBlocking

runBlocking { println(“”) delay(1000) }

runBlocking {
    println("")
    delay(1000)}Copy the code

This function also creates the scope of a coroutine, but it ensures that the current thread is blocked until all code in the coroutine completes execution, but is only recommended for testing.

4.launch

runBlocking {
    launch{
    println("")
    delay(1000)
    }
    launch{
    println("")
    delay(1000)}}Copy the code

This function can be used only in the scope of the coroutine, and then creates child coroutines in the scope of the current coroutine. If the outer coroutine terminates, all coroutines in this scope will terminate.

5.suspend

suspend fun printDelay() {
    println("")
    delay(1000)}Copy the code

Used to wrap part of code in a method and declare it as a suspended function. Suspended functions can call each other, but do not provide coroutine scope.

6.coroutineScope

suspend fun printDelay()=coroutineScope {
    launch{
    println("")
    delay(1000)}}Copy the code

First, coroutineScope is also a pending function, and inherits the external coroutineScope and creates a child coroutine. This solves the above problem, and it does the same thing as runBlocking to ensure that all code in the coroutine executes.

7. Take the elimination procedure

val job=GlobalScope.launch{
    println("")
    delay(1000)
}
job.cancel()
Copy the code

The launch function returns a Job object and calls the cancel function to remove the coroutine.

8. Obtain the returned result

runBlocking {
    println("")
    val result=async{
    6*2
    }.await()
    delay(1000)}Copy the code

Async functions can create a child coroutine and return a Deferred object. If we want to get execution results in the aa=sync code block, we call await function of the Deferred object. When we call await function, the current coroutine will be blocked if the code has not finished executing.

9. Obtain the returned result in parallel

runBlocking {
    println("")
    val result=async{
    6*2
    }
    val result1=async{
    6+8
    }
    Log.i(""."result is ${result.await()+result1.await()}")
    delay(1000)}Copy the code

Call await function with 2 async functions at the end and it becomes concurrent execution.

10.withContext

runBlocking {
    val result=withContext(Dispatchers.Default){
    6*2
    }
    delay(1000)}Copy the code

Similar to async functions, blocks of code are immediately executed while the external coroutine is suspended. When the code block is finished executing, the last line of code is returned as the return value. Unlike async functions, withContext forces a thread parameter. There are three options for this parameter (1) dispatchers. Default for low concurrency thread policy, suitable for computation-intensive tasks (2) dispatchers. IO for high concurrency thread policy, suitable for executing code that is blocking and waiting most of the time, For example, the network request (3) dispatchers. Main means that the child thread is not started and the code is executed in the Main thread, which is only available in Android code

Any function except the coroutineScope function can specify a thread parameter, but withContext forces a thread parameter.