Hi guys, hope you are doing well. Sorry for this n...
# coroutines
j
Hi guys, hope you are doing well. Sorry for this noob question, I’m trying to understand the concurrency concepts when using coroutines. My questions is, is it posible to execute concurrently a couple of suspending functions in the same coroutine?
s
Yup, absolutely. Call 'launch' or 'async' a bunch of times on the same CoroutineScope and call your suspending functions inside these 'launch/'async' calls.
j
But, what if launch or async runs on a Main Dispatcher where there is only one thread available?
s
Since suspend functions are not blocking (are yours blocking?), they can still run asynchronously (although not parallel)
j
Do you mean with (although not parallel) is that this will be sequenced one behind other suspend but you do not control when they completes. For me this looks like blocking
Copy code
scope.launch(onlyOneThreadDispatcher) {
    suspendFunc1()
    suspendFunc1()
}
This will be blocking, does not will?
e
launch { suspend1() }; launch { suspend2()
may run interleaved at suspend points even if the executor only has one thread. that's kinda the whole point?
☝️ 1
s
Copy code
scope.launch { suspendFunc1() }
scope.launch { suspendFunc2() }
More like the above. The calls to launch return immediately and the two suspendFuncs run asynchronously. In your example, Jimmy, where they are called inside the same one launch call, they run sequentially. But, sequentially or asynchronously, they are never blocking. They are suspending. Unless you put actual blocking code inside of them (eg Thread.sleep() or waiting for a socket, etc)
d
All of the above create new coroutines though.
launch
starts a new coroutine. So technically the answer is: No, one coroutine only ever executes one suspending function at a time. However coroutines are cheap, so you can just launch as many as you need.
e
You're right, Take, but the new coroutines are child coroutines in the parent's scope. So, if it helps to understand the concept, you can imagine the children as running and suspending concurrently when viewed from the parent, if they don't block all the scope's resources (e.g. if it has 1 thread and makes a blocking instead of suspending call). What you're saying essentially is right and means that a coroutine can only run things sequentially (if it doesn't do classic threading), but it has the ability to suspend and launch (fork) other coroutines. In itself it doesn't run things in parallel, but it does have the power to be running in parallel, or have children run in parallel.
j
I think i have doubts about suspending and blocking code, for me makes sense what Take Weiland said. In the example i put above, lets say
suspendFunc1()
function is a remote call, in my understanding
suspendFunc2()
will not be executed until remote call completes, even if it is
suspend
So, even if the function is suspend it is blocking the coroutine, isn’t it?
Thanks in advance for you replies, makes a lot easier my understanding!!!!!
e
Yes in your example the first suspending call runs and has to complete before the second suspending call. That's not what you call blocking, that's just sequential code: the first goes before the second. Because the first is marked with the
suspend
modifier, it indicates that the function might suspend while running (e.g. of it is awaiting results from a network call). A good implementation will not block, but suspend execution, which will later resume.
In other words: 2 sequential function calls do not run concurrently, simply because they are called one after another. However, if you sequentially start new child coroutines (like Take explained very well), they have the possibility to run in parallel (if their context is multi threaded) or asynchronously, i.e. not synchronously with the scope that launched them.
j
WHen you said is supended while is waiting a remote call response seem similar to what we can see in launching Futures in java.
Like, the call is in progress