Blog Infos
Author
Published
Topics
,
Published
Definition (in context to programming):

  1. What are coroutines and how to create coroutines using coroutine builders in Kotlin?
  2. What aJob is and the different states a Jobcan be in?
Kotlin coroutines & structured concurrency
val parentJob = launch {
val childJob = launch {
var count = 1
while (count <= 5) {
println("Count: $count")
delay(100)
count++
}
}
}
delay(250)
println("Cancelling parent job")
parentJob.cancel()
-----------
OUTPUT:
Count: 1
Count: 2
Count: 3
Cancelling parent job
fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    // ...
): Job
Understanding cancellation
  • Whether the execution of code in a coroutine should continue or not after cancel() is invoked, is a decision that lies in the hands of a developer, which will, in turn, depend on the use case.
  • Execution of code within a coroutine even after cancel() is invoked does not mean that structured concurrency is violated since the parent Job will still wait for the children Job(s) to reach a final state before reaching its final state. A Job is in a final state when its isCompleted = true and we can use join() in our code to wait for the completion of a Job before executing any further code.
val parentJob = launch {
val childJob = launch {
var count = 1
val startTime = System.currentTimeMillis()
var nextPrintTime = startTime
while (count <= 5) {
if (System.currentTimeMillis() >= nextPrintTime) {
println("Count: $count")
nextPrintTime += 100L
count++
}
}
}
}
delay(250)
println("Cancelling parent job")
parentJob.cancel()
parentJob.join()
println("Parent job completed")
-----------
OUTPUT:
Count: 1
Count: 2
Count: 3
Cancelling parent job // cancels parentJob and hence, cancels childJob recursively
Count: 4 // childJob continues executing its code
Count: 5
Parent job completed // parentJob completes only after childJob. (Structured Concurrency)

Job Offers

Job Offers


    Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

    Senior Android Software Engineer (f/m/d)

    Paradox Cat GmbH
    Munich
    • Full Time
    apply now

    Android Test Automation Engineer

    Komoot
    Remote
    • Full Time
    apply now

OUR VIDEO RECOMMENDATION

,

At long last we have Kotlin first at Meta!

Android started to support Kotlin 5 years ago and became the first-choice language three years ago. But Meta just announced Kotlin as the preferred and default language for our Android code base only 3 months…
Watch Video

At long last we have Kotlin first at Meta!

Peng Jiang & Sergei Rybalkin
Software Engineer & Kotlin
Meta

At long last we have Kotlin first at Meta!

Peng Jiang & Serge ...
Software Engineer & ...
Meta

At long last we have Kotlin first at Meta!

Peng Jiang & Ser ...
Software Engineer & Kotli ...
Meta

Jobs

while (count <= 5 && isActive)
Parallel Decomposition
suspend fun performTasks(task1: String, task2: String) {
    val job1 = async { doTask(task1) }
    val job2 = async { doTask(task2) }
    mergeTasks(job1.await(), job2.await())
}
fun CoroutineScope.launch(
    // ...
    block: suspend CoroutineScope.() -> Unit
): Job
  • The Job can be directly written and executed within the lambda block of anotherJob, to implicitly use it as its scope. For instance:
val parentJob = launch {
    val childJob = launch { ... }
}
  • In a suspending function, you can wrap your code into a
    coroutineScope { … } block that establishes a boundary of your operation, its scope.
suspend fun performTasks(task1: String, task2: String) {
    coroutineScope {
        val job1 = async { doTask(task1) }
        val job2 = async { doTask(task2) }
        mergeTasks(job1.await(), job2.await())
    }
}
CoroutineContext vs CoroutineScope

This sounds confusing, doesn’t it? Let’s simplify this by defining CoroutineContext and CoroutineScope.

 

fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    // ...
): Job

CoroutineScope: It is just a wrapper around the context, that is, it is an interface that consists of a sole property — val coroutineContext: CoroutineContext. It has nothing else but context.

public interface CoroutineScope {
    public val coroutineContext: CoroutineContext
}
val parallelJob = launch {
delay(1000)
}
val parentJob = launch {
val childJob = launch(parallelJob) { // Notice how the context is explicitly provided
var count = 1
while (count <= 5) {
println("Count: $count")
delay(100)
count++
}
}
}
delay(250)
println("Cancelling parent job")
parentJob.cancel()
parentJob.join()
println("Parent job completed")
-----------
OUTPUT:
Count: 1
Count: 2
Count: 3
Cancelling parent job
Parent job completed
Count: 4
Count: 5 // childJob continues after parentJob (CoroutineScope),
// and is bound to parallelJob (CoroutineContext)

💡If you’re curious and wish to dive deeper into CoroutineContext and CoroutineScope, here’s a great blog.

 

YOU MAY BE INTERESTED IN

YOU MAY BE INTERESTED IN

blog
It’s one of the common UX across apps to provide swipe to dismiss so…
READ MORE
blog
Hi, today I come to you with a quick tip on how to update…
READ MORE
blog
Automation is a key point of Software Testing once it make possible to reproduce…
READ MORE
blog
Drag and Drop reordering in Recyclerview can be achieved with ItemTouchHelper (checkout implementation reference).…
READ MORE

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.

Menu