Coroutines order

import kotlinx.coroutines.*

fun main() = runBlocking {
launch {
println(“in sub coroutine ${Thread.currentThread().name}”)
}
println(“before coroutine in main ${Thread.currentThread().name}”)
withContext(Dispatchers.IO) {
println(“hello from coroutine ${Thread.currentThread().name}”)
delay(1500)
println(“hello from coutoutine after delay ${Thread.currentThread().name}”)
}
println(“after coroutine in main ${Thread.currentThread().name}”)
}

Is there a question?

Ohh yes uhmm the output is kind of strange to me
This is it
before coroutine in main main @coroutine#1

hello from coroutine DefaultDispatcher-worker-1 @coroutine#1

in sub coroutine main @coroutine#2

hello from coutoutine after delay
DefaultDispatcher-worker-1 @coroutine#1

after coroutine in main main @coroutine#1
I am wondering why the Dispatch IO is called before the launch, seeing as launch is invoked on main thread , it should be fone before dispatch.io is called

launch will start a new coroutine with the default dispatcher. This means the default dispatcher will schedule the launch imediately, but it might not execute it directly. It could decide to launch it on a different thread. Since this is a multi threaded environment there isn’t any way to predict which of the 2 paths will be executed first.
For example when I just ran your code I got this result

before coroutine in main main @coroutine#1
in sub coroutine main @coroutine#2
hello from coroutine DefaultDispatcher-worker-1 @coroutine#1
hello from coutoutine after delay DefaultDispatcher-worker-1 @coroutine#1
after coroutine in main main @coroutine#1

That isn’t really what I am asking, it’s Scheduled to run yeah, it’s meant to execute before going into the with Context block, launch is used to start a Coroutine on a worker thread , while the withContext here is dispatched to the IO thread, normally the launch close is meant to be executed before even entering the Dispatch.IO

I’m’ not an expert on coroutines, but every new coroutine is bound to the context of the coroutine that starts it. The coroutine you start with launch is bound to it’s parent context (in this case runBlocking). This means that it will finish executing before the runBlocking function returns. If you really want to wait for launch block finish executing you can use the Job returned by it.


I’m really not an expert on kotlin coroutines. I only used them sparingly and I’m definetly wrong on terminology and details. That said I should still be true on the basics in this case. In any case you should read through some more resources on coroutines. I’d start with the documentation on jobs or better still read through the entire coroutine guide:

https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html

And if this does not help there are people here that know far more about coroutines than I do. So don’t hesitate to ask more questions.

normally the launch close is meant to be executed before even entering the Dispatch.IO

No, launch starts a coroutine and it must be executed inside the runBlocking lifetime, as @Wasabi375 said.

Please format your code next time, and propose a valid snipped (your code does not compile), thank you.

This still proves my point, it’s in the runBlocking scope, meaning it should be executed before even entering another Coroutine scope, do you get me , it should be executed first before dispatching you the IO

For launch, the parent scope (and transitively any ancestor scope) won’t be marked as complete until the launched coroutine is done, but that’s it. There’s no other ordering guarantee of any kind with any other coroutine, and the code after launch runs right away (launch is not a suspend method). launch is designed for executing work in parallel, it wouldn’t be very good at its job if it blocked other coroutines from running.

Read the Coroutines Guide, it should clear up the confusion.

No, it shouldn’t. That’s not how coroutines work. As @nickallendev says, there’s no ordering guarantee. If you need one coroutine to finish before you start another, you can use join, await, or withContext.

Also, you’re not entering another scope, you’re just switching to a different dispatcher.