Can't understand why current thread remains the sa...
# coroutines
p
Can't understand why current thread remains the same after exiting from withContext. Code with comments is in thread.
Copy code
val pool = Executors.newSingleThreadExecutor { runnable -> Thread(runnable, "The1") }
val pool2 = Executors.newSingleThreadExecutor { runnable -> Thread(runnable, "The2") }

suspend fun main() {
    println("1 " + Thread.currentThread().name) // main
    withContext(pool.asCoroutineDispatcher()) {
        println("2 " + Thread.currentThread().name) // The1
    }
    println("3 " + Thread.currentThread().name) // The1 ?? Why not main ??
    withContext(pool2.asCoroutineDispatcher()) {
        println("4 " + Thread.currentThread().name) // The2 
    }
    println("5 " + Thread.currentThread().name) // The2 ?? Why not main ??
    pool.shutdownNow()
    pool2.shutdownNow()
}
c
In that example there is no original dispatcher for
withContext
to dispatch to, hence it resumes directly in the invoking thread (the thread running the
withContext
block). You can change the behaviour by wrapping everything in
withContext(Dispatchers.Default)
, for example, or any other dispatcher of your choosing.
withContext
uses
suspendCoroutineUninterceptedOrReturn
which is documented as:
Invocation of Continuation.resumeWith resumes coroutine directly in the invoker’s thread without going through the ContinuationInterceptor that might be present in the coroutine’s CoroutineContext. It is the invoker’s responsibility to ensure that a proper invocation context is established. Continuation.intercepted can be used to acquire the intercepted continuation.
…`resumeWith` in the code path is called only when there is no dispatcher, otherwise it submits the continuation to the last dispatcher.
🙏 1
s
What Chris said. Maybe the suspend main function is run on the Unconfined dispatcher, which, when resumed, may run on any thread, most likely the one that was just active before it resumed. The only thing that is guaranteed by calling a suspend function is that subsequent invocations are always executed synchronously/sequentially. Only the context of their dispatcher determines the actual (pool of) (virtual) threads.
🙏 1