Coroutine context and dispatchers
Coroutine context
Coroutines always execute in some context represented by a value of the CoroutineContext
type
The coroutine context is a set of various elements:
- Job: A cancellable piece of work, which has a defined lifecycle
- ContinuationInterceptor: A mechanism which listens to the continuation within a coroutine and intercepts its resumption.
- CoroutineExceptionHandler: A construct which handles exceptions in coroutines.
1 2 3 4 5 6 7 8 9 |
|
Dispatchers and threads
The coroutine context includes a coroutine dispatcher that determines what thread or threads the corresponding coroutine uses for its execution.
All coroutine builders like launch
and async
accept an optional CoroutineContext
parameter that can be used to explicitly specify the dispatcher for the new coroutine and other context elements.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
It produces the following output (maybe in different order):
1 2 3 4 |
|
Thread used | Max number of threads | Useful when | |
---|---|---|---|
Dispatchers.Default | thread pool | Number of CPU cores | Executing CPU-bound code |
Dispatchers.IO | thread pool | Defined in IO_PARALLELISM_PROPERTY_NAME. The default value is max(64, number of cpu cores) | Executing IO-heavy code |
Dispatchers.Main | main | 1 | Working with UI elements |
executorService.asCoroutineDispatcher() | thread pool | Defined by ExecuteService config | Need to limit number of threads that the coroutine can run in |
runBlocking {...} | Currently thread | 1 | Bridging blocking and suspending code |
Unconfined vs confined dispatcher
The Dispatchers.Unconfined coroutine dispatcher starts a coroutine in the caller thread, but only until the first suspension point. After suspension it resumes the coroutine in the thread that is fully determined by the suspending function that was invoked.
1 2 3 4 5 6 7 8 9 10 |
|
Produces the output:
1 2 3 4 |
|
So, the coroutine with the context inherited from runBlocking {...}
continues to execute in the main
thread, while the unconfined one resumes in the default executor thread that the delay
function is using.