ChildJob's body is
posted to main thread and execution proceed to
delay(3000)
immediately (e.g. so if you put
Log.d(TAG, "before delay(3000)")
before
delay(3000)
you will see that log is always there before
Child Started
) . As I said concurrent code is non-deterministic (unpredictable) in general. In your piece of code if main thread hangs for 2s+ after the
delay(3000)
call you will see the logs from the second screenshots.
So here is a potential timeline of what is happening in your case
1.
Parent Started
log is printed
2. Child job is posted to main thread (its execution
hasn't started!
Child Started
isn't printed)
3. delay(3000) is executed, effectively posting
Parent Ended
Log with 3000ms delay.
4. Main thread somehow hangs for 2100ms (e.g. there was some heavy runnable in the main thread)
5. Child job is executing,
Child Started
printed.
Child Ended
posted with 1000ms delay
6. delay(3000) from step 3 completes,
Parent Ended
printed
7. delay(1000) from step 5 completes,
Child Ended
printed.
One potential way to make this
particular example predictable is to add start parameter to child's launch
val childJob = launch(start = CoroutineStart.UNDISPATCHED) {
in this case you will ensure
delay(1000)
is scheduled strictly before
delay(3000)
.
Overall don't try to make a concurrent code predictable/pseudo-serial by using just delays - it will never work properly in 100% of real scenarios