SupervisorJob
和 Job
的区别SupervisorJob
和 Job
是 Kotlin 协程中的两种 Job
类型,它们的主要区别在于 异常处理 和 子任务的传播行为。让我们详细看看它们的不同点:
Job
(默认 Job)Job
是协程的基本任务单元,协程可以嵌套,父协程和子协程之间是层级关系。val parentJob = Job()
val child1 = CoroutineScope(Dispatchers.Default + parentJob).launch {
println("Child 1 started")
delay(1000)
println("Child 1 completed")
}
val child2 = CoroutineScope(Dispatchers.Default + parentJob).launch {
println("Child 2 started")
delay(500)
throw Exception("Child 2 failed") // 失败后会取消整个 parentJob
}
runBlocking {
child1.join()
child2.join()
}
在这个例子中,child2
抛出异常,导致 parentJob
和所有其他子协程(包括 child1
)都被取消,child1
将无法完成。
SupervisorJob
SupervisorJob
也是协程层级结构的一部分,但它的行为不同于普通的 Job
。SupervisorJob
的一个关键特性是 异常不传播。如果一个子协程失败,不会影响其他子协程,也不会导致父协程被取消。每个子协程的异常只会影响它自己。val supervisorJob = SupervisorJob()
val child1 = CoroutineScope(Dispatchers.Default + supervisorJob).launch {
println("Child 1 started")
delay(1000)
println("Child 1 completed")
}
val child2 = CoroutineScope(Dispatchers.Default + supervisorJob).launch {
println("Child 2 started")
delay(500)
throw Exception("Child 2 failed") // 失败不会影响其他子协程
}
runBlocking {
child1.join()
child2.join()
}
在这个例子中,即使 child2
抛出异常并失败,child1
仍然可以继续执行并完成。
特性 | Job |
SupervisorJob |
---|---|---|
异常传播 | 子协程异常会取消父协程及其所有子协程 | 子协程异常不会影响父协程或其他子协程 |
父子协程的取消行为 | 子协程异常会传播到父协程及其他子协程 | 父协程和其他子协程不受影响 |
适用场景 | 子协程之间强耦合,某个子协程失败需要整体取消 | 子协程之间解耦,子任务独立运行 |
Job
适合的场景:
SupervisorJob
适合的场景:
Job
vs SupervisorJob
?Job
。SupervisorJob
。