Bird
Raised Fist0
Kotlinprogramming~20 mins

Job lifecycle and cancellation in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Job Lifecycle Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this coroutine job cancellation code?
Consider the following Kotlin code using coroutines. What will be printed when this code runs?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        repeat(3) { i ->
            println("Working on $i ...")
            delay(100L)
        }
    }
    delay(250L)
    job.cancel()
    job.join()
    println("Done")
}
AWorking on 0 ...\nWorking on 1 ...\nDone
BWorking on 0 ...\nWorking on 1 ...\nWorking on 2 ...\nDone
CWorking on 0 ...\nDone
DDone
Attempts:
2 left
💡 Hint
Think about when the job is cancelled and how many iterations complete before cancellation.
🧠 Conceptual
intermediate
1:30remaining
Which state does a Job enter after calling cancel() but before completion?
In Kotlin coroutines, after you call cancel() on a Job but before it finishes, what is the Job's state?
AActive
BCancelled
CNew
DCompleting
Attempts:
2 left
💡 Hint
Think about the transition phase between active and fully cancelled.
🔧 Debug
advanced
2:30remaining
Why does this coroutine not cancel as expected?
Examine the code below. The job.cancel() is called, but the coroutine keeps running. Why?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        for (i in 1..5) {
            Thread.sleep(100L)
            println("Working $i")
        }
    }
    delay(250L)
    job.cancel()
    job.join()
    println("Finished")
}
Adelay() inside the coroutine is missing, so cancellation is ignored.
BThread.sleep blocks the thread and prevents cancellation checks inside the coroutine.
CThe coroutine is not cancellable because it uses launch instead of async.
Djob.cancel() was called too late after the coroutine finished.
Attempts:
2 left
💡 Hint
Consider how blocking calls affect coroutine cancellation.
📝 Syntax
advanced
1:30remaining
Which option correctly cancels a Job and waits for its completion?
Select the Kotlin code snippet that cancels a Job and waits until it finishes properly.
A
job.cancel()
job.join()
B
job.cancel()
job.cancelAndJoin()
Cjob.cancelAndJoin()
D
job.join()
job.cancel()
Attempts:
2 left
💡 Hint
Look for the built-in function that combines cancel and join.
🚀 Application
expert
2:30remaining
How many times will 'Task running' print before cancellation?
Given the code below, how many times will 'Task running' be printed before the job is cancelled?
Kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        repeat(10) { i ->
            if (!isActive) return@launch
            println("Task running $i")
            delay(50L)
        }
    }
    delay(230L)
    job.cancelAndJoin()
    println("Job cancelled")
}
A5
B6
C4
D7
Attempts:
2 left
💡 Hint
Calculate how many 50ms delays fit into 230ms before cancellation.

Practice

(1/5)
1. Which of the following best describes the lifecycle of a Kotlin Job?
easy
A. A job is always active and never completes.
B. A job starts cancelled and then becomes active.
C. A job starts active, can be cancelled, and then completes.
D. A job completes before it starts.

Solution

  1. Step 1: Understand Job lifecycle states

    A Kotlin Job begins in an active state, meaning it is running or ready to run.
  2. Step 2: Recognize cancellation and completion

    A Job can be cancelled to stop its work, and after finishing or cancellation, it reaches a completed state.
  3. Final Answer:

    A job starts active, can be cancelled, and then completes. -> Option C
  4. Quick Check:

    Job lifecycle = active -> cancelled -> completed [OK]
Hint: Jobs start active, then cancel or complete [OK]
Common Mistakes:
  • Thinking jobs start cancelled
  • Assuming jobs never complete
  • Confusing job states order
2. Which Kotlin code snippet correctly cancels a job and waits for its completion?
easy
A. job.cancelAndJoin()
B. job.cancel()
C. job.start()
D. job.join()

Solution

  1. Step 1: Identify cancellation with waiting

    The method cancelAndJoin() cancels the job and suspends until it finishes.
  2. Step 2: Differentiate from other methods

    cancel() only requests cancellation without waiting; join() waits but doesn't cancel; start() begins a job.
  3. Final Answer:

    job.cancelAndJoin() -> Option A
  4. Quick Check:

    Cancel and wait = cancelAndJoin() [OK]
Hint: Use cancelAndJoin() to cancel and wait [OK]
Common Mistakes:
  • Using cancel() without waiting
  • Confusing join() with cancel
  • Calling start() to cancel
3. What will be the output of this Kotlin coroutine code?
val job = CoroutineScope(Dispatchers.Default).launch {
    repeat(3) { i ->
        println("Working on $i...")
        delay(100)
    }
}
job.cancel()
Thread.sleep(500)
medium
A. Prints all three "Working on" lines
B. Prints some "Working on" lines before stopping
C. Throws a cancellation exception
D. Prints no output

Solution

  1. Step 1: Analyze job launch and cancellation

    The job starts and prints "Working on 0...", then delays. The cancel() is called immediately after launch.
  2. Step 2: Understand cancellation effect

    Because cancellation happens quickly, some iterations may run before the job stops, so partial output appears.
  3. Final Answer:

    Prints some "Working on" lines before stopping -> Option B
  4. Quick Check:

    Partial output due to quick cancel [OK]
Hint: Cancel stops job but may print partial output [OK]
Common Mistakes:
  • Expecting all lines printed
  • Expecting no output at all
  • Assuming exception is printed
4. Identify the error in this Kotlin coroutine cancellation code:
val job = CoroutineScope(Dispatchers.Default).launch {
    try {
        repeat(5) {
            println("Working...")
            delay(100)
        }
    } catch (e: Exception) {
        println("Cancelled")
    }
}
job.cancelAndJoin()
medium
A. Missing job.start() before cancel
B. cancelAndJoin() should be called inside launch
C. delay() cannot be used inside launch
D. Catching Exception does not handle cancellation properly

Solution

  1. Step 1: Understand cancellation exception type

    Cancellation throws CancellationException, which is a subclass of Throwable but not Exception.
  2. Step 2: Recognize catch block limitation

    Since CancellationException is not caught by catch (e: Exception), the cancellation is not handled as intended.
  3. Final Answer:

    Catching Exception does not handle cancellation properly -> Option D
  4. Quick Check:

    Catch CancellationException, not Exception [OK]
Hint: Catch CancellationException, not Exception [OK]
Common Mistakes:
  • Catching Exception instead of CancellationException
  • Calling cancelAndJoin() incorrectly
  • Thinking delay() is invalid inside launch
5. You want to safely cancel a long-running job and perform cleanup after cancellation. Which Kotlin coroutine pattern achieves this correctly?
hard
A. Use job.cancelAndJoin() then run cleanup code after it returns.
B. Call job.cancel() and immediately start a new job for cleanup.
C. Ignore cancellation and let the job finish naturally.
D. Call job.join() without cancelling, then cleanup.

Solution

  1. Step 1: Understand safe cancellation

    Using cancelAndJoin() cancels the job and waits until it fully stops, ensuring no work is left running.
  2. Step 2: Perform cleanup after cancellation

    After cancelAndJoin() returns, it's safe to run cleanup code because the job is fully cancelled.
  3. Final Answer:

    Use job.cancelAndJoin() then run cleanup code after it returns. -> Option A
  4. Quick Check:

    Cancel and wait before cleanup = cancelAndJoin() [OK]
Hint: Cancel and wait before cleanup with cancelAndJoin() [OK]
Common Mistakes:
  • Starting cleanup before job stops
  • Ignoring cancellation
  • Using join() without cancelling
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard