Mohamad Abuzaid 1 year ago
mohamad-abuzaid #kotlin

Kotlin Coroutines (3/3)

Our final article in our series. More Coroutines components.

If you haven’t already, It is recommended to read the previous 2 articles first:

In this third and final article we will cover the following topics in Kotlin Coroutines:

  • Coroutines Channel.
  • Coroutines Select.
  • Coroutines vs RxKotlin
  • Coroutines vs Threads

--------------

[5] Coroutines Channels


Channels are a way to send and receive values between coroutines in Kotlin. They provide a mechanism for coordinating the execution of coroutines and exchanging data between them. Channels are based on the concept of pipelines, where data is passed from one stage of processing to the next.

A channel can be thought of as a queue, where values can be added to one end and removed from the other end. The key difference between channels and queues is that channels are non-blocking and allow for cooperation between coroutines. This means that coroutines can wait for data to be available in a channel, or can produce data in a channel and then continue executing, without being blocked.

Channels can be used for a variety of purposes, including:

  • Communication between coroutines: You can use channels to send data from one coroutine to another.
  • Flow control: Channels allow you to control the flow of data between coroutines, and to ensure that data is processed in the order in which it is produced.
  • Synchronization: Channels can be used to synchronize the execution of coroutines, and to ensure that data is processed in the correct order.
fun main() = runBlocking {
    val channel = Channel<Int>()
    launch {
        for (x in 1..5) {
            println("Sending $x")
            channel.send(x)
        }
        channel.close()
    }
    for (y in channel) {
        println("Received $y")
    }
    println("Done!")
}

Here, we create a channel of type Int and then launch a coroutine that adds the values 1 through 5 to the channel. The main coroutine then receives the values from the channel and prints them. The channel is closed when all values have been added to it, and the main coroutine terminates when there are no more values to receive.

--------------

[6] Coroutines Select


In coroutines, select is a powerful operator that allows you to wait for the first result from multiple possible sources. It can be thought of as a non-blocking version of a switch statement in other programming languages.

The select operator works by suspending the execution of a coroutine until one of the sources is ready. When a source is ready, its result is chosen, and the corresponding branch of the select statement is executed. This allows you to perform multiple operations in parallel and choose the first to complete.

select is useful when you need to wait for multiple channels, for example. It provides a way to multiplex multiple channels onto a single channel, or to merge multiple channels into one.

fun main() = runBlocking {
    val channel1 = Channel<Int>()
    val channel2 = Channel<Int>()

    launch {
        for (x in 1..5) {
            channel1.send(x * 2)
        }
        channel1.close()
    }
    launch {
        for (x in 1..5) {
            channel2.send(x * 3)
        }
        channel2.close()
    }

    repeat(10) {
        select<Unit> {
            channel1.onReceive { value ->
                println("Received from channel 1: $value")
            }
            channel2.onReceive { value ->
                println("Received from channel 2: $value")
            }
        }
    }

    println("Done!")
}

In this example, we launch two coroutines that send values to two different channels. The main coroutine then uses select to wait for the first value from either channel. The onReceive block is executed when a value is available, and the value is printed to the console. The select statement is repeated 10 times, so that we receive 10 values in total. The program terminates when all values have been received.

-------------

Coroutines vs RxKotlin


Coroutines and RxKotlin are both frameworks for asynchronous programming in Kotlin, but they differ in their approach and use cases.

Coroutines are a language feature in Kotlin that provide a lightweight way to write asynchronous, non-blocking code. They are designed for writing sequential, sequential-like, and parallel code. They are well suited for writing small, composable asynchronous tasks and are easy to integrate with existing code.

RxKotlin, on the other hand, is a reactive programming library that is built on top of the ReactiveX API. It is designed for writing complex, event-driven applications and provides a way to handle data streams that are emitted over time. RxKotlin provides a rich set of operators for transforming and aggregating streams of data, and makes it easy to handle errors and cancellation.

So, while coroutines are good for writing small, composable tasks, RxKotlin is better suited for complex, event-driven applications where you need to handle streams of data. In general, the choice between coroutines and RxKotlin will depend on the specific needs of your application.

----------------

Coroutines vs Threads


Coroutines and threads are two different mechanisms for executing code concurrently in Kotlin.

Threads are a low-level mechanism for executing code in parallel, and they are provided by the operating system. They are heavyweight and have a lot of overhead, which makes them unsuitable for fine-grained concurrency. When using threads, you have to manage synchronization and coordination yourself, which can be error-prone and difficult to debug.

Coroutines, on the other hand, are a high-level mechanism for executing code concurrently in Kotlin. They are lightweight, have much less overhead than threads, and are designed for fine-grained concurrency. They are easier to manage and coordinate than threads and provide a rich set of primitives for managing asynchronous operations.

So, while threads are well suited for low-level system programming, coroutines are better suited for writing high-level, user-facing code. When writing a Kotlin application, you should generally prefer coroutines over threads, as they are easier to use, easier to manage, and provide a higher-level API. However, if you need to write low-level system code, or if you are using a library that requires you to use threads, you may need to use threads in your Kotlin code.

1
863
How to create custom annotations in Kotlin

How to create custom annotations in Kotlin

1675112374.jpg
Mohamad Abuzaid
6 months ago
OkHttp Interceptors

OkHttp Interceptors

1675112374.jpg
Mohamad Abuzaid
1 year ago
Security in Android App Development (2/3)

Security in Android App Development (2/3)

1675112374.jpg
Mohamad Abuzaid
7 months ago
Kotlin Delegated Properties

Kotlin Delegated Properties

1675112374.jpg
Mohamad Abuzaid
1 year ago
Kotlin Scope Functions

Kotlin Scope Functions

1675112374.jpg
Mohamad Abuzaid
1 year ago