SupervisorJob vs Job: virheiden eristäminen
Käyttäkää SupervisorJobia estämään yhden lapsen virheen aiheuttama sisarusten peruutus.
SupervisorJob vs Job: virheiden eristäminen on ilmainen Kotlin Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Kotlin Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Jobin oletusarvoinen virheiden välitys
Tavallisen Job-työn kanssa lapsen epäonnistuminen peruuttaa vanhemman, joka puolestaan peruuttaa kaikki sisarukset. Yksi virhe kaataa koko hierarkian.
import kotlinx.coroutines.*
fun main() = runBlocking {
try {
coroutineScope {
launch { delay(50); throw RuntimeException("child 1 failed") }
launch { delay(1000); println("child 2 — never prints") }
}
} catch (e: RuntimeException) {
println("Caught: ${e.message}")
}
}SupervisorJobin yleiskatsaus
SupervisorJob muuttaa sääntöä: lapsen epäonnistuminen EI peruuta sisaruksia tai vanhempaa. Jokainen lapsi epäonnistuu itsenäisesti.
import kotlinx.coroutines.*
fun main() = runBlocking {
val supervisor = SupervisorJob()
val scope = CoroutineScope(coroutineContext + supervisor)
scope.launch { throw RuntimeException("child 1 failed") }
scope.launch { delay(100); println("child 2 still runs") }
delay(200)
supervisor.cancel()
}supervisorScope-rakentaja
supervisorScope { } luo scopet, jonka vanhempana on SupervisorJob. Se on suositusten mukainen tapa suorittaa toisistaan riippumattomia lapsia.
import kotlinx.coroutines.*
fun main() = runBlocking {
supervisorScope {
val job1 = launch {
throw RuntimeException("job1 failed")
}
val job2 = launch {
delay(100)
println("job2 succeeded")
}
job1.join() // wait for job1 (it failed)
job2.join() // job2 is unaffected
}
}Lapsien virheiden käsittely
supervisorScope-scopessa jokainen lapsi käsittelee oman poikkeuksensa. Lapsien käsittelemättömät poikkeukset on otettava kiinni kunkin lapsen kohdalla erikseen.
import kotlinx.coroutines.*
fun main() = runBlocking {
supervisorScope {
val result = async {
delay(50)
throw RuntimeException("async failed")
}
try {
result.await()
} catch (e: RuntimeException) {
println("Caught from async: ${e.message}")
}
println("Scope continues")
}
}Job ja SupervisorJob scopen luonnin yhteydessä
Välitä SupervisorJob(), kun luot CoroutineScopen palvelulle tai ViewModellille, jonka pitäisi selviytyä yksittäisten lapsien epäonnistumisista.
import kotlinx.coroutines.*
class MyService {
private val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
fun startTask(name: String) {
scope.launch {
if (name == "fail") throw RuntimeException("$name failed")
println("$name done")
}
}
fun stop() = scope.cancel()
}
fun main() = runBlocking {
val svc = MyService()
svc.startTask("fail")
svc.startTask("ok")
delay(100)
svc.stop()
}viewModelScope käyttää SupervisorJobia
Androidin viewModelScope perustuu SupervisorJob-työhön. Yhden launch-kutsun epäonnistuminen ei peruuta ViewModelin muita korutiineja.
import kotlinx.coroutines.*
// Android ViewModel internals:
// val viewModelScope = CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
// Each launch is independent — one failure doesn't crash the ViewModel
fun main() = runBlocking {
println("viewModelScope = SupervisorJob + Main")
}Rinnakkainen hajauttaminen supervisorScopen avulla
Käyttäkää supervisorScope + async -rakennetta rinnakkaisiin tehtäviin, joissa jotkin tehtävät voivat epäonnistua vaikuttamatta muihin.
import kotlinx.coroutines.*
fun main() = runBlocking {
val results = supervisorScope {
val a = async { delay(50); "result-A" }
val b = async { throw RuntimeException("B failed") }
val c = async { delay(30); "result-C" }
listOf(
runCatching { a.await() },
runCatching { b.await() },
runCatching { c.await() }
)
}
results.forEach { println(it) }
}Milloin tavallista Jobia käytetään
Käyttäkää tavallista Job-rakennetta (coroutineScope), kun kaikkien lasten on onnistuttava yhdessä — yhden epäonnistumisen tulee keskeyttää koko ryhmä. Se toimii kuin transaktio: kaikki tai ei mitään.
import kotlinx.coroutines.*
fun main() = runBlocking {
try {
coroutineScope { // regular Job
val a = async { delay(50); "A" }
val b = async { throw RuntimeException("B failed") }
println(a.await())
println(b.await()) // throws — cancels a too
}
} catch (e: RuntimeException) {
println("Transaction failed: ${e.message}")
}
}Poikkeusten välittyminen supervisorScopessa
supervisorScope-rakenteessa poikkeus välittyy scopeen vain, jos se karkaa lapsen ylimmältä tasolta — eli lapsessa ei ole try-catch-käsittelyä. Vanhempi ei näe sitä.
import kotlinx.coroutines.*
fun main() = runBlocking {
supervisorScope {
// Exception caught inside child — scope unaffected
launch {
try { throw RuntimeException("handled") }
catch (e: Exception) { println("Child caught: ${e.message}") }
}
delay(100)
println("Scope survived")
}
}CoroutineExceptionHandler ja SupervisorJob
Asentakaa CoroutineExceptionHandler supervisor-scopeen, jotta voitte kirjata käsittelemättömät lapsen epäonnistumiset lokiin tai reagoida niihin ilman, että scope kaatuu.
import kotlinx.coroutines.*
fun main() = runBlocking {
val handler = CoroutineExceptionHandler { _, e ->
println("Uncaught: ${e.message}")
}
val scope = CoroutineScope(SupervisorJob() + handler)
scope.launch { throw RuntimeException("unhandled failure") }
scope.launch { delay(100); println("still running") }
delay(200)
scope.cancel()
}Eristettyjen epäonnistumisten yhteenveto
Job: yksi lapsi epäonnistuu → kaikki epäonnistuvat. SupervisorJob: lapset epäonnistuvat toisistaan riippumatta. Käyttäkää supervisoria palveluihin ja ViewModeleihin sekä tavallista Jobia transaktionaalisiin ryhmiin.
import kotlinx.coroutines.*
// Decision table:
// coroutineScope { } -> Job: all-or-nothing
// supervisorScope { } -> SupervisorJob: independent failures
// CoroutineScope(SupervisorJob()) -> long-lived service
fun main() = runBlocking { println("Pick the right job for the right scope") }Pikatarkistus
Mikä scope estää lapsen epäonnistumista peruuttamasta sisaruksiaan?
Kertaus
Job: epäonnistuminen leviää sisaruksiin. SupervisorJob/supervisorScope: epäonnistumiset eristetään lapsikohtaisesti. Käyttäkää supervisorScopea rinnakkaisiin, toisistaan riippumattomiin tehtäviin ja tavallista coroutineScopea transaktionaalisiin ryhmiin.
Opi Kotlin tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 51
- Oppitunnit
- 203
Usein kysytyt kysymykset
Onko oppitunti ”SupervisorJob vs Job: virheiden eristäminen” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Kotlin Academy-oppimispolun 3 oppituntia, myös oppitunnin “SupervisorJob vs Job: virheiden eristäminen”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Kotlin Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”SupervisorJob vs Job: virheiden eristäminen”?
Käyttäkää SupervisorJobia estämään yhden lapsen virheen aiheuttama sisarusten peruutus. Harjoittelet Kotlin Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Kotlin Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Kotlin Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”SupervisorJob vs Job: virheiden eristäminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Kotlin Academy-oppitunnilla?
Kyllä. Jokainen Kotlin Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- SupervisorJob vs Job: virheiden eristäminen
- CoroutineExceptionHandler: maailmanlaajuinen käsittelemätön poikkeusten käsittelijä
- async/await-poikkeusten eteneminen
- Vikasietoisten korutiiniarkkitehtuurien suunnittelu