Home > Enterprise >  does coroutines in Kotlin work like threads?
does coroutines in Kotlin work like threads?

Time:07-20

So I am trying to learn kotlin coroutines for networking purposes on Android but I don't understand how they work. What am I missing in the code to make it work like a thread (the two counters should mix together ) ? Should I use something else than runBlocking {} ?

import kotlinx.coroutines.*

suspend fun counter(a: Int) {
    for(n in 0..a) {
        print(n.toString()   " ")
    }
}

fun main() {
    runBlocking {
        counter(10)
        launch {
            counter(10)
        }
    }
}

output : 0 1 2 3 4 5 6 7 8 9 10 0 1 2 3 4 5 6 7 8 9 10

CodePudding user response:

There is no simple answer to "does coroutines work like threads?". It really depends on the context. From some perspective you can say they work like threads, from other they do not.

In your specific case I would say: yes, they work similarly to threads. You can launch two coroutines, so they will work concurrently and in parallel and you will see logs mixed together. There are two reasons why you don't see this in your example.

First, you launch() your second coroutine only after the first already finished. You have to use launch() twice or reorder your code to launch() first and then do counter():

launch {
    counter(10)
}
counter(10)

Second, runBlocking() is very special in a way that by default it creates a single-threaded dispatcher. That means coroutines could work concurrently, but not in parallel. You can compare this to spawning two threads on a single-core CPU - both threads will run eventually, however, they have to wait for each other.

There are two ways to fix this. You can use a multi-threaded dispatcher:

runBlocking(Dispatchers.Default) {
    launch {
        counter(10)
    }
    counter(10)
}

Or you can keep using only a single thread, but make your coroutines cooperatively yield their thread for other coroutines:

for(n in 0..a) {
    print(n.toString()   " ")
    yield()
}

Alternatively, instead of yield() you can use delay() or suspend the execution in any other way.

CodePudding user response:

The subject you're talking about is called Race Conditions, which coroutines in Kotlin prevent that from happening. I recommend you to take this quick official tutorial on Kotlin Coroutines by Google: https://developer.android.com/codelabs/basic-android-kotlin-training-introduction-coroutines

This will answer all your questions.

  • Related