Chang Kenneth
02/08/2022, 6:44 AM//sampleStart
fun main() = runBlocking {
repeat(100_000) { // launch a lot of coroutines
launch {
delay(5000L)
print(".")
}
}
}
Casey Brooks
02/08/2022, 6:39 PMlaunch
-ed code according to the CoroutineDispatcher
being used, with its own scheduling algorithms. Ultimately, every suspension point will go back to the Dispatcher and allow it a chance to suspend the code and allow other code to run while suspended, even in a single-threaded context (such as Dispatchers.Main
, or the entire JS runtime environment). I don't know the specific scheduling algorithms used, because you shouldn't need to be thinking at that low of a level with coroutines. What's important is that launch
signifies that each block will run in parallel, and delay()
is a non-blocking delay
The only time a coroutine will be truly "blocked" is if your code is hogging the CPU and doesn't have any suspension points. delay()
, regardless of the specific scheduling algorithm, does not block the thread, and will yield itself to allow other coroutines to run while it is still suspended. So that example will always take ~5 seconds to complete regardless of how many coroutines you have, because they're all running in parallelChang Kenneth
02/09/2022, 9:15 AMCasey Brooks
02/09/2022, 3:09 PMChannel
. Use Flows
for processing/filtering/mapping events in a reactive stream like RxJava. Use launch { }
to run multiple jobs in parallel, or async { }.await()
if you want to run in parallel and then aggregate their results.
tl;dr: coroutines are very deep and have a lot of little details, but the intention is that you can basically ignore all of that. Focus on learning the coroutines API surface, the stuff outlined here, because that's all you'll really need in a normal application. Those other constructs are there to allow one to build entirely new coroutines-based APIs (new patterns for concurrent/async work), but are not intended for everyday use.