https://kotlinlang.org logo
#coroutines
Title
# coroutines
p

Paul Martin

04/30/2020, 7:17 PM
hi everyone. total n00b question here. all help gratefully received. 🙏 i've got this code, which is based on one of the examples from the kotlinlang.org docs:
Copy code
fun main() = runBlocking {
    launch {
        println("block 1: start")
        delay(2000)
        println("block 1: end")
    }
    launch {
        println("block 2: start")
        delay(1000)
        println("block 2: end")
    }

    Unit
}
as expected, the output is:
Copy code
block 1: start
block 2: start
block 2: end
block 1: end
so the two
launch
blocks are running concurrently. next i try and replace the
delay
calls with some functions of my own:
Copy code
fun functionThatTakesALongTime() {
    for (j in 1..5) {
        for (i in 1..1_000_000_000) {
            i * i * i
        }
    }
}

fun functionThatTakesAShortTime() {
    1 + 1
}

fun main() = runBlocking {
    launch {
        println("block 1: start")
        functionThatTakesALongTime()
        println("block 1: end")
    }
    launch {
        println("block 2: start")
        functionThatTakesAShortTime()
        println("block 2: end")
    }

    Unit
}
this time the output is this:
Copy code
block 1: start
block 1: end
block 2: start
block 2: end
in other words it ran the whole of the first
launch
block before starting on the second one. want i want is for them to run concurrently as in the first example. i guess there's something fundamental that i'm missing! what is it about
delay
which enables the
launch
blocks to run concurrently? thanks!
o

octylFractal

04/30/2020, 7:18 PM
delay
suspends while it waits, which allows the other
launch
block to run on the same single thread that is available
this might help if you're not aware of suspending vs. blocking https://medium.com/@elye.project/understanding-suspend-function-of-coroutines-de26b070c5ed
p

Paul Martin

04/30/2020, 7:30 PM
thank you - i understand now why this works like this.
i think i'm getting my head around it now. apparently what i actually want is for my two functions to run in parallel, not concurrently. i didn't appreciate that they mean two different things.
i think the docs are not very clear in this respect. the examples make it seem like two functions with a
delay
in them can be running in parallel, but they're actually running concurrently in a single thread
o

octylFractal

04/30/2020, 8:15 PM
yes, though I think the issue is that requires understanding more about suspension and
runBlocking
it's part of the issue where you don't want the documentation to be too much at once, but you also need to touch on important concepts
I think the docs could do better at emphasizing what suspending really means though
u

uli

05/01/2020, 12:07 PM
runBlocking defaults to using the blocked thread for it's dispatcher. So it is single threaded.
You can pass Dispatcher.default as parameter to run blocking and your code works as expected again
s

svenjacobs

05/04/2020, 3:13 PM
runBlocking
should imho only be used in tests... when you replace
runBlocking
with
with(GlobalScope)
your code should run in parallel as expected. Note that the usage of
GlobalScope
is okay for your little test application but usually there are more granular scopes that should be used.
u

uli

05/06/2020, 10:45 PM
main will then terminate before the coroutines finish @svenjacobs
s

svenjacobs

05/10/2020, 5:57 PM
Right, in this case best work with
async
and
await
Or wait on the
Job
returned by
launch
with
join
u

uli

05/10/2020, 10:03 PM
Or use runBlocking 😁
s

svenjacobs

05/13/2020, 7:31 AM
I though problem by OP was that
launch
inside
runBlocking
do not run concurrently? 🤔
4 Views