Kotlin coroutine and use summary in Android (six channel)

Channel

Deferred objects provide a convenient way to pass values ​​between coroutines. Channel is used to pass a stream of values ​​between coroutines.

Channel is a bit similar to BlockingQueue. The difference is that BlockingQueue's put and take operations are blocking, while Channel's send and receive are non-blocking that can be suspended.

fun main() = runBlocking {
    val channel = Channel<Int>()
    launch {
        // this might be heavy CPU-consuming computation or async logic, we'll just send five squares
        for (x in 1..5) channel.send(x * x)
    }
    // here we print five received integers:
    repeat(5) { println(channel.receive()) }
    println("Done!")
}

Unlike Queue, the channel can be closed. For the closing of the channel, we can use close (). The value transmitted before closing will still be received at the receiving end. The receiving end traverses the received value through a for loop:

fun main() = runBlocking {
    val channel = Channel<Int>()
    launch {
        for (x in 1..5) channel.send(x * x)
        channel.close() // we're done sending
    }
    // here we print received values using `for` loop (until the channel is closed)
    for (y in channel) println(y)
    println("Done!")
}

In the previous blog post, we introduced that when the launch of flow is too fast and the processing speed is too slow, you can take corresponding measures. You can return a ReceiveChannel through produce , and the receiver traverses through consumeEach , as follows:

fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
    for (x in 1..5) send(x * x)
}

fun main() = runBlocking {
    val squares = produceSquares()
    squares.consumeEach { println(it) }
    println("Done!")
}

By defining extension functions on CoroutineScope to create coroutines to achieve structured concurrency, avoid using global coroutines Scope (GlobalScope) everywhere, coroutines created by producers can be nested and called as follows:

fun main() = runBlocking {
    val numbers = produceNumbers() // produces integers from 1 and on
    val squares = square(numbers) // squares integers
    repeat(5) {
        println(squares.receive()) // print first five
    }
    println("Done!") // we are done
    coroutineContext.cancelChildren() // cancel children coroutines
}

fun CoroutineScope.produceNumbers() = produce<Int> {
    var x = 1
    while (true) send(x++) // infinite stream of integers starting from 1
}

fun CoroutineScope.square(numbers: ReceiveChannel<Int>): ReceiveChannel<Int> = produce {
    for (x in numbers) send(x * x)
}

Fan-out and fan-in of channel

Buffered channels 和 Ticker channels

Multiple coroutines may receive values ​​from the same channel. This situation is called Fan-out.
Multiple coroutines may transmit values ​​to the same channel. This situation is called Fan-in.
Channel can be set to a buffer size when it is defined, similar to BlockingQueue.
Considering that these scenes are not used much, I will not introduce them for the time being. If you want to know, you can directly move to the official website document: https://kotlinlang.org/docs/reference/coroutines/channels.html

Published 82 original articles · Like 86 · Visit 110,000+

Guess you like

Origin blog.csdn.net/unicorn97/article/details/105219082