2
votes

According to the documentation, a delay suspends a coroutine but doesn't block a thread:

Delay is a special suspending function. It suspends the coroutine for a specific time. Suspending a coroutine does not block the underlying thread, but allows other coroutines to run and use the underlying thread for their code.

However when running this code:

fun main() {

    println("1")
    GlobalScope.launch {
        doSomething()
        delay(1000L)
        println("3")
    }
    GlobalScope.launch {
        delay(1000L)
        println("4")
    }
    println("5")
}

suspend fun doSomething() {

    delay(500L)
    println("2")
    delay(1000L)
}

the output given is:

1
5
2
4
3 

According to my understanding, it should have shown 1 5 4 2 3. That's because doSomething() is being called in the first coroutine and so the delay is more as compared to the second coroutine and the second coroutine is called asynchronously. Where is my misunderstanding?

Also with this piece of code, both the values are printed together after 2 seconds:

fun main() {

    GlobalScope.launch {

        val value1 = doSomething1()
        val value2 = doSomething2()
        println(value1)
        println(value2)
    }
}

suspend fun doSomething1(): String {

    delay(1000L)
    return "This is the answer1"
}

suspend fun doSomething2(): String {

    delay(1000L)
    return "This is the answer2"
}

Why is this?

2

2 Answers

3
votes

TL;DR

No, delays in different jobs don't affect each other.


For your first problem, clearly 1 and 5 are first and last so we can ignore those. So for the rest of them we have:

Print Delays Total delay
2 500 500
3 500, 1000, 1000 2500
4 1000 1000

So the order would be 2, 4, 3 which you've verified with the output.

If you want to see a bit more how the coroutines are running, we can consider what's happening with each job at roughly each time step:

Time Job 1 Job 2
0 delay(500L) delay(1000L)
500 print("2"); delay(1000L) -
1000 - print("4")
1500 delay(1000L) -
2000 - -
2500 print("3") -

To address your second problem, you can just write it as one block of code:

GlobalScope.launch {

    delay(1000L)
    val value1 = "This is the answer1"
    delay(1000L)
    val value2 = "This is the answer2"
    println(value1)
    println(value2)
}

Clearly the print statements would run one after another. Just because there was a delay in obtaining the values, doesn't mean there is a delay between printing them. The behaviour that I think you're expecting would occur if the print statements were in the two doSomething methods.

1
votes
so the delay is more as compared to the second coroutine

No, the first delay is: 500L, and the second delay is: 1000L