// Created on savesnippets.com ยท https://savesnippets.com/vhdrUEAJQTmQBs import kotlinx.coroutines.* fun main() = runBlocking { // Cooperative โ€” uses delay() which checks for cancellation val job1 = launch { repeat(100) { i -> println("polite: $i") delay(50) // cancellation checkpoint } } delay(180) job1.cancel() job1.join() // BAD โ€” no suspend points, won't cancel val job2 = launch { var i = 0 while (i < 1_000_000_000) { i++ // tight CPU loop, no cancellation check if (i % 100_000_000 == 0) println("loop: $i") } println("finished loop") } delay(50) job2.cancel() // ignored job2.join() // waits for the whole loop to finish // FIX โ€” sprinkle ensureActive() or yield() inside CPU loops val job3 = launch { var i = 0 while (i < 1_000_000_000) { i++ if (i % 100_000 == 0) ensureActive() // throws on cancel } } delay(20) job3.cancelAndJoin() println("job3 cancelled") }