Scheduler

This is another concept we discussed briefly in Chapter 8, Threads and Coroutines, in the Starting a coroutine section. 

Remember how our launch() or async() could receive CommonPool?

Here's an example to remind you that you could specify it explicitly:

// Same as launch {}
launch(CommonPool) {
...
}

// Same as async {}
val result = async(CommonPool) {
...
}

This CommonPool is a Scheduler design pattern in a bad disguise. Many async tasks may be mapped to the same Scheduler.

Run the following code:

val r1 = async(CommonPool) {
for (i in 1..1000) {
println(Thread.currentThread().name)
yield()
}
}

r1.await()

What is interesting is the fact that the same coroutine is picked up by different threads:

ForkJoinPool.commonPool-worker-2
ForkJoinPool.commonPool-worker-3
...
ForkJoinPool.commonPool-worker-3
ForkJoinPool.commonPool-worker-1

You can also specify the context as Unconfined:

val r1 = async(Unconfined) {
...
}

This will run the coroutine on the main thread. It prints:

main
main
...

You can also inherit context from your parent coroutine:

val r1 = async {
for (i in 1..1000) {
val parentThread = Thread.currentThread().name
launch(coroutineContext) {
println(Thread.currentThread().name == parentThread)
}
yield()
}
}

Note though, that running in the same context doesn't mean that we run on the same thread.

You may ask yourself: what's the difference between inheriting the context and using Unconfined? We'll discuss this in detail in the next section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.138.195