Unconfined

common
val Unconfined: CoroutineDispatcher

A coroutine dispatcher that is not confined to any specific thread. It executes the initial continuation of a coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid stack overflows.

Event loop

Event loop semantics is a purely internal concept and have no guarantees on the order of execution except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost unconfined coroutine.

For example, the following code:

withContext(Dispatchers.Unconfined) {
println(1)
withContext(Dispatchers.Unconfined) { // Nested unconfined
println(2)
}
println(3)
}
println("Done")

Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed. But it is guaranteed that "Done" will be printed only when both withContext calls are completed.

If you need your coroutine to be confined to a particular thread or a thread-pool after resumption, but still want to execute it in the current call-frame until its first suspension, then you can use an optional CoroutineStart parameter in coroutine builders like launch and async setting it to the value of CoroutineStart.UNDISPATCHED.

val Unconfined: CoroutineDispatcher
val Unconfined: CoroutineDispatcher
val Unconfined: CoroutineDispatcher

A coroutine dispatcher that is not confined to any specific thread. It executes initial continuation of the coroutine in the current call-frame and lets the coroutine resume in whatever thread that is used by the corresponding suspending function, without mandating any specific threading policy. Nested coroutines launched in this dispatcher form an event-loop to avoid stack overflows.

Event loop

Event loop semantics is a purely internal concept and have no guarantees on the order of execution except that all queued coroutines will be executed on the current thread in the lexical scope of the outermost unconfined coroutine.

For example, the following code:

withContext(Dispatchers.Unconfined) {
println(1)
withContext(Dispatchers.Unconfined) { // Nested unconfined
println(2)
}
println(3)
}
println("Done")

Can print both "1 2 3" and "1 3 2", this is an implementation detail that can be changed. But it is guaranteed that "Done" will be printed only when both withContext are completed.

Note that if you need your coroutine to be confined to a particular thread or a thread-pool after resumption, but still want to execute it in the current call-frame until its first suspension, then you can use an optional CoroutineStart parameter in coroutine builders like launch and async setting it to the the value of CoroutineStart.UNDISPATCHED.

Sources

common source
Link copied to clipboard
js source
Link copied to clipboard
jvm source
Link copied to clipboard
native source
Link copied to clipboard