...

/

I/O Dispatchers

I/O Dispatchers

Learn about I/O dispatchers and how they work with a custom or fixed pool of threads.

The Dispatchers.IO dispatcher is designed to be used when we block threads with I/O operations—for instance, when we read/write files, use Android shared preferences, or call blocking functions. The code below takes around one second because Dispatchers.IO simultaneously allows more than 50 active threads.

package kotlinx.coroutines.app
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlin.system.measureTimeMillis

suspend fun main() {
    val time = measureTimeMillis {
        coroutineScope {
            repeat(50) {
                launch(Dispatchers.IO) {
                    Thread.sleep(1000)
                }
            }
        }
    }
    println(time)
}
Blocking I/O operations using Dispatcher.IO

How does it work? Imagine an unlimited pool of threads. Initially, it’s empty, but as we need more threads, they’re created and kept active until we don’t use them for some time. Such a pool exists, but it wouldn’t be safe to use it directly. With too many active threads, the performance degrades slowly but without limits, eventually causing out-of-memory errors. This is why we create dispatchers with a limited number of threads they can use simultaneously. The number of cores in our processor limits Dispatchers.Default. The limit of Dispatchers.IO is 64 (or the number of cores if there are more).

package kotlinx.coroutines.app
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch

suspend fun main() = coroutineScope {
    repeat(1000) {
        launch(Dispatchers.IO) {
            Thread.sleep(200)

            val threadName = Thread.currentThread().name
            println("Running on thread: $threadName")
        }
    }
}
Dispatchers with a limited number of threads

As we mentioned, both Dispatchers.Default ...