Kotlin coroutines — delay vs sleep

Vairavan Srinivasan
2 min readMay 18, 2019

Kotlin coroutines supports delay as a suspend function and this has an interesting side effect when compared with a Thread.sleep.

In the following example, coroutines are launched for each item of the list using the async builder. Launched coroutines each wait for a delay for 2 seconds.

Running this gives this result. All items are processed with just a little over 2 seconds despite each coroutine delaying by 2 seconds.

Processing value 1
Processing value 2
Processing value 3
Processed in 2026 ms

Replacing delay with a Thread.sleep() results in this,

Processing value 1
Processing value 2
Processing value 3
Processed in 6027 ms

To make things interesting, runBlocking is not associated with a dispatcher backed by a thread pool. It just uses a main thread. So how is a single main thread launching multiple coroutines (each delaying by 2 seconds) able to complete in a little above 2 seconds? This is the case when the list has 100 items.

This is because of the implementation of delay as an event loop dispatch mechanism. For Android developers, this is conceptually same as a HandlerThread posting a delayed runnable to its message queue. Delay is implemented by associating dequeue timestamp with a message posted to the message queue and this ensures that the thread stays unblocked while the looper periodically checks for the dequeue criteria.

--

--