'How to run two jobs in parallel but wait for another job to finish using kotlin coroutines
I have these jobs below:
- Inflating a complex calendar view async
- Downloading events A
- Downloading events B
- Adding calendar view to it's parent
- Adding A events to the calendar
- Adding B events to the calendar
I want
- 1, 2, 3 have to start async,
- 4 has to wait for 1
- 5 has to wait for 2 and 4
- 6 has to wait for 3 and 4
- 6 and 5 should not be dependent to each other, can run at different times.
- 4 is only dependent to 1, so it can run before 2 or 3 is finished.
I've tried async await but it makes them finish at the same time (as expected). I think this example might be a good way to learn parallel programming concepts, like semaphores mutex or spin locks. But it's too complicated for me to understand.
How should I implement these with using Kotlin coroutines?
Solution 1:[1]
It's pretty straightforward. All you need to do is:
- Implement
CoroutineScopeand createCoroutineContext, or useGlobalScope. - Using local
CoroutineScopeorGlobalScope.launch()launch the coroutine. - In the coroutine use
async/awaitto run/wait asynchronous operations.
You can apply next code to your algorithm (all explanations are in the comments):
class SomeClass : CoroutineScope {
private var job: Job = Job()
// creating local CoroutineContext
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
// cancel the Job if it is no longer needed
fun onClear() {
job.cancel()
}
fun doJob() {
// launch coroutine
launch {
// run Job1, Job2, Job3 in parallel, asyncIO - is an extension function on CoroutineScope
val d1 = asyncIO { job1() }
val d2 = asyncIO { job2() }
val d3 = asyncIO { job3() }
// waiting for result of Job1
val job1Result = d1.await()
// run Job4
val d4 = asyncIO { job4(job1Result) }
// waiting for result of Job2 and Job4
val job2Result = d2.await()
val job4Result = d4.await()
// run Job5
val d5 = asyncIO { job5(job2Result, job4Result) }
// waiting for result of Job3
val job3Result = d3.await()
// run Job6
val d6 = asyncIO { job6(job3Result, job4Result) }
onDone(d5.await(), d6.await())
}
}
private fun onDone(job5Result: String, job6Result: String) {
// do something with result of Job5 and Job6
}
fun job1(): String {
return "Result of job1"
}
fun job2(): String {
return "Result of job2"
}
fun job3(): String {
return "Result of job3"
}
fun job4(job1Result: String): String {
return "Result of job4"
}
fun job5(job2Result: String, job4Result: String): String {
return "Result of job5"
}
fun job6(job3Result: String, job4Result: String): String {
return "Result of job6"
}
// extension function
fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() }
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
