How to increase Kotlin coroutines Dispatchers.IO size on Android?

Viewed 4722

Coroutines Dispatchers.IO context is limited to 64 threads. That's not enough to reliably interface with blocking code in highly-concurrent system.

Documentation states that:

Additional threads in this pool are created and are shutdown on demand. The number of threads used by this dispatcher is limited by the value of “kotlinx.coroutines.io.parallelism” (IO_PARALLELISM_PROPERTY_NAME) system property. It defaults to the limit of 64 threads or the number of cores (whichever is larger).

I want to change kotlinx.coroutines.io.parallelism system property to something else. However, if I just do this:

adb shell "setprop kotlinx.coroutines.io.parallelism 1000"

then I get the following result:

setprop: failed to set property 'kotlinx.coroutines.io.parallelism' to '1000'

Furthermore, if I want to ship my app, then I'll need to change this property on users' devices as well, right? Otherwise the app won't work. However, even assuming that it's possible, as far as I understand, all apps that change this property will override the setting for one another. This doesn't sound like a reliable mode of operation.

So, I have three questions in this context:

  1. Is the property implied in documentation is indeed the "system property" that I tried to change?
  2. How to change this property on non-rooted device for all users of my app?
  3. Is there better alternative?

P.S. I know that if I'd only use coroutines, without blocking code, this wouldn't be a problem (probably). But let's just assume that I need to use blocking calls (e.g. legacy Java code).

3 Answers

IO_PARALLELISM_PROPERTY_NAME does not refer to an Android system property, but to a Java system property. Just add this code early in your app, e.g. first in your Application.onCreate(), to change it to 1000:

import static kotlinx.coroutines.DispatchersKt.IO_PARALLELISM_PROPERTY_NAME;

System.setProperty(IO_PARALLELISM_PROPERTY_NAME, Integer.toString(1000));

This does not have to be done on a per-device basis with root or anything like that. It will work everywhere, since it is regular app code using regular app APIs.

As long as you do this before you use Dispatchers.IO for the first time, your property change will be applied.

You can create your own dispatcher with any number of threads, like so

val dispatcher = Executors.newFixedThreadPool(128).asCoroutineDispatcher()
Related