Shubhang B
Shubhang B

Reputation: 59

Does Kotlin delay use a dispatcher internally to unblock the caller thread?

This is some test code I am using to learn kotlin coroutines. The code works as expected and takes about 1 Second to print the sum, but now If I replace delay(1000) by a blocking call like a network request, then the code takes about 10 seconds to print the sum ( each call takes around 1 second), but if I wrap the network call in a withContext and use the IO dispatcher it takes 1 second to print the sum, because it is run on a different thread. Does the delay function use some kind of a dispatcher to unblock the thread?


suspend fun asyncDoubleFn(num: Int): Int {
    delay(1000)
    return num * 2
}


fun main() = runBlocking {
    launch {
        val tt = measureTimeMillis {
            val results = mutableListOf<Deferred<Int>>()
            for (num in 0..10) {
                val result = async { asyncDoubleFn(num + 1) }
                results.add(result)
            }
            val sum = results.map { it.await() }.reduce { acc, i -> acc + i }
            println("[SUM]: $sum")
        }

        println("[TT]: $tt")
    }


    launch {
        println("Another coroutine")
    }

    println("Main Code")


}

Upvotes: 1

Views: 728

Answers (1)

Marko Topolnik
Marko Topolnik

Reputation: 200148

Does the delay function use some kind of a dispatcher to unblock the thread?

Not just delay. All suspendable functions interact with the dispatcher.

The question you should ask is: "Which dispatcher is in charge here?"

And the answer is: runBlocking installs its own dispatcher that dispatches to the thread it is called on. Both launch and async in your code inherit it.

With this in mind:

If I replace delay(1000) by a blocking call like a network request, then the code takes about 10 seconds to print the sum (each call takes around 1 second)

Each blocking call will hold on to the single thread of the dispatcher. It won't be able to do any other work while being blocked.

but if I wrap the network call in a withContext and use the IO dispatcher it takes 1 second to print the sum, because it is run on a different thread

Yes, this changes the dispatcher, problem solved.

So, what does delay do? It suspends the current coroutine (the one that async launched) and returns the control to the dispatcher, which can now go on to resume your loop and start the next coroutine.

Upvotes: 2

Related Questions