# Questions about coroutines from a newcomer

**URL:** <https://discuss.kotlinlang.org/t/questions-about-coroutines-from-a-newcomer/10151>\
**Category:** Support\
**Created:** [November 3, 2018, 5:30pm UTC](https://discuss.kotlinlang.org/t/questions-about-coroutines-from-a-newcomer/10151 "2018-11-03T17:30:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![ktiniatros](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@ktiniatros](https://discuss.kotlinlang.org/u/ktiniatros)\
**Post date:** [November 3, 2018, 5:30pm UTC](https://discuss.kotlinlang.org/t/questions-about-coroutines-from-a-newcomer/10151/1 "2018-11-03T17:30:02Z")

</div>

Hello,

I started playing with coroutines and I have couple of questions about this tutorial:  
[https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html](https://kotlinlang.org/docs/reference/coroutines/cancellation-and-timeouts.html)

Question 1:  
If you remove job.join() from the following snippet, the result does not change. What’s the point of using it? Is there anything harmful if I don’t use it?

```
    val job = launch {
    repeat(1000) { i ->

            println("I'm sleeping $i ...")

        delay(500L)

    }

}

delay(1300L) // delay a bit

println("main: I'm tired of waiting!")

job.cancel() // cancels the job

job.join() // waits for job's completion 

println("main: Now I can quit.”)

```

Question 2: In kotlin coroutines, you cannot cancel computation code. Instead you can check the cancelation status with isActive rather than having computation code like in this example:

```
val startTime = System.currentTimeMillis()
val job = launch(Dispatchers.Default) {

    var nextPrintTime = startTime

    var i = 0

    while (isActive) { // cancellable computation loop

        // print a message twice a second

        if (System.currentTimeMillis() >= nextPrintTime) {

            println("I'm sleeping ${i++} ...")

            nextPrintTime += 500L

        }

    }

}

delay(1300L) // delay a bit

println("main: I'm tired of waiting!")

job.cancelAndJoin() // cancels the job and waits for its completion

println("main: Now I can quit."

```

BUT: if you use while(isActive && i\<5), it does not respect the computation code, it only respects the isActive. On the contrary, it gets ever more weird if you use while(isActive || i\<5), cause in this case it checks both (waiting for i to become 5 before terminating)! Why is that?

PS: I’m testing the aforementioned examples in unit tests in Android Studio using Kotlin 1.3.0.

---

<div class="post-metadata">

**Author:** ![Varia](https://avatars.discourse-cdn.com/v4/letter/v/b9e5f3/32.png) [@Varia](https://discuss.kotlinlang.org/u/Varia)\
**Post date:** [November 3, 2018, 8:55pm UTC](https://discuss.kotlinlang.org/t/questions-about-coroutines-from-a-newcomer/10151/2 "2018-11-03T20:55:43Z")

</div>

Regarding question 1:  
Cancelling a job does not force the job to stop immediately. Instead, a `CancellationException` is thrown at the current (if the job is suspended) or next (if it is not) suspension point. That means that additional code may be executed in the job if 1) the job is not currently suspended, 2) the exception is caught, or 3) a `finally` block is places somewhere. This allows the job to perform any cleanup needed before stopping.

To see the effect of `join`, try running the below code:

```run-kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(1000) { i ->
                println("I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
            println("Cleaning up")
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancel() // cancels the job
    job.join() // waits for job's completion 
    println("main: Now I can quit.")    
}

```

Next, try running the same code without the `join`:

```run-kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            repeat(1000) { i ->
                println("I'm sleeping $i ...")
                delay(500L)
            }
        } finally {
            println("Cleaning up")
        }
    }
    delay(1300L) // delay a bit
    println("main: I'm tired of waiting!")
    job.cancel() // cancels the job
    // job.join() // waits for job's completion 
    println("main: Now I can quit.")    
}

```
