JP
03/16/2020, 9:37 AMRun the code and check the log; we can see that all the coroutines still run on the main UI thread. We haven’t yet employed multithreading in any way, but already we have the benefits of running coroutines concurrently!
It’s very easy for us to change this code to run “contributors” coroutines on different threads from the common thread pool. Specifyas the context argument for theDispatchers.Defaultfunction:async
async(Dispatchers.Default) { ... }```
I’m sort of confused. If I don’t specify a dispatcher in the argument for
async function, isn’t the default dispatcher Dispatchers.Default? Yet, I did see the logs change
from
147 [AWT-EventQueue-0] INFO Contributors - Clearing result
2251 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - kotlin: loaded 54 repos
2678 [AWT-EventQueue-0 @coroutine#7] INFO Contributors - kotlin-benchmarks: loaded 7 contributors
...
to
164 [AWT-EventQueue-0] INFO Contributors - Clearing result
2172 [AWT-EventQueue-0 @coroutine#1] INFO Contributors - kotlin: loaded 54 repos
2527 [DefaultDispatcher-worker-5 @coroutine#10] INFO Contributors - anko-example: loaded 2 contributors
2621 [DefaultDispatcher-worker-5 @coroutine#9] INFO Contributors - kotlinx.html: loaded 15 contributors
...
But when I read the comments in the source code of Builders.common.kt, it was stated like this:
* Coroutine context is inherited from a [CoroutineScope], additional context elements can be specified with [context] argument.
* If the context does not have any dispatcher nor any other [ContinuationInterceptor], then [Dispatchers.Default] is used.
* The parent job is inherited from a [CoroutineScope] as well, but it can also be overridden
* with corresponding [context] element.
and in Dispatchers.kt , it was stated:
/**
* The default [CoroutineDispatcher] that is used by all standard builders like
* [launch][CoroutineScope.launch], [async][CoroutineScope.async], etc
* if no dispatcher nor any other [ContinuationInterceptor] is specified in their context.
*
* It is backed by a shared pool of threads on JVM. By default, the maximal level of parallelism used
* by this dispatcher is equal to the number of CPU cores, but is at least two.
* Level of parallelism X guarantees that no more than X tasks can be executed in this dispatcher in parallel.
*/
@JvmStatic
public actual val Default: CoroutineDispatcher = createDefaultDispatcher()
Could someone explain what I’m missing?Joffrey
03/16/2020, 9:48 AMJoffrey
03/16/2020, 9:50 AMDico
03/16/2020, 9:51 AMCoroutineScope?JP
03/16/2020, 10:47 AMCoroutineScope or within another suspending function.Joffrey
03/16/2020, 10:48 AM"The default dispatcher for the runBlocking coroutine, in particular, is confined to the invoker thread, so inheriting it has the effect of confining execution to this thread with predictable FIFO scheduling."
https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#unconfined-vs-confined-dispatcherJoffrey
03/16/2020, 10:49 AMrunBlocking does provide a Dispatcher that is not the Default , that’s why you have to specify Default if you want it in child coroutinesJP
03/16/2020, 11:13 AMrunBlocking the default dispatcher is not the Default. This I noticed for the first time. I just checked the code once again, and tried to find the parent context. It was not runBlocking, but:
main.kt calls ContributorsUI class instance, which implements Contributors interface, which again implements CoroutineScope interface. The Contributors interface has method loadContributors which calls the suspending function loadContributorsConcurrent , in which the async call happens.
And I found out inside Contributors interface the code:
val job: Job
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
I guess this code set the parent context’s dispatcher to Dispatchers.Main, right?
P.S. How should I interpret the expression job + Dispatchers.Main? Could someone give a link to read about this? I found in Jobs.kt
public operator fun plus(other: Job) = other
but I think I found the wrong code to read about.Joffrey
03/16/2020, 11:14 AMI guess this code set the parent context’s dispatcher toIt sets this context’s dispatcher to, right?Dispatchers.Main
Main, and therefore any child coroutine will inherit it by default, unless you specify another one.JP
03/16/2020, 11:15 AMJoffrey
03/16/2020, 11:17 AMHow should I interpret the expression? Could someone give a link to read about this?job + Dispatchers.Main
CoroutineContext is a set of elements and using + allows to add/combine such elements (like Job or Dispatcher or CoroutineName) to a context. This is explained in the article I linked in my first reply.JP
03/16/2020, 11:18 AMJoffrey
03/16/2020, 11:18 AMJoffrey
03/16/2020, 11:21 AM+ operator overloading: https://kotlinlang.org/docs/reference/operator-overloading.html#operator-overloadingJP
03/16/2020, 11:23 AMplus in Jobs.kt , but I guess it’s the plus defined in CoroutineContext which is called.Joffrey
03/16/2020, 11:24 AMCoroutineContext type, rather than Job, in order to enable combining other kinds of CoroutineContext elements