π‘ ꡬ쑰νλ λμμ±μ μ΄μ΄μ Jobκ³Ό child μ½λ£¨ν΄μ νΉμ§μ λνμ¬ νμ΅νμμ΅λλ€.
Coroutine Job?
- Jobμ μ½λ£¨ν΄μ μ·¨μνκ³ , μνλ₯Ό νμ νλ λ± λ€μνκ² μ¬μ©λ μ μλ 컨ν μ€νΈμ λλ€.
- μλͺ μ£ΌκΈ°λ₯Ό κ°μ§λ©° μΈν°νμ΄μ€ μ λλ€.
- ꡬ체μ μΈ μ¬μ©λ²κ³Ό μνλ₯Ό κ°μ§κ³ μλ€λ μ μμ μΆμ ν΄λμ€μ²λΌ λ€λ£° μ μμ΅λλ€.
Coroutine Job μν λμλ
- μλμ κ°μ΄ 6κ°μ§ μνμ λμνλ‘ λνλΌ μ μμ΅λλ€.
- μ€μ μ½λμμλ toStringμ νμ©ν΄ μ‘μ μνλ₯Ό λ³Ό μ μμ΅λλ€.
- Active
- μ‘μ΄ μ€νλκ³ μ½λ£¨ν΄μ΄ μ‘μ μνν©λλ€.
- μ‘μ΄ μ½λ£¨ν΄ λΉλμ μν΄ μμ±λμμ λ, λ³Έμ²΄κ° μ€νλλ μνμ΄λ©° μμ μ½λ£¨ν΄μ μμν μ μμ΅λλ€.
- New
- λλΆλΆ μ½λ£¨ν΄μ Active μνλ‘ μμλμ§λ§, μ§μ° μμλλ μ½λ£¨ν΄μ New μνλ‘ μμλ©λλ€.
- New → Activeλ‘ μ ννλ €λ©΄ μμ μ΄ μ€νλμ΄μΌ ν©λλ€.
- Completing
- μμ μ μ€νμ΄ μλ£λλ©΄ λ³ννλ μνμ λλ€.
- Completed
- μμλ€μ μ€νμ΄ λͺ¨λ λλ μνμ λλ€.
- Cancelling
- μ‘μ΄ μ€ν λμ€μ μ·¨μλκ±°λ μ€ν¨νκ² λλ μνμ λλ€.
- μ¬κΈ°μμ λμ€μ New μνλ ν΄λΉνμ§ μμΌλ©°, Activeλ Complet-ing μνμμλ§ μ¬ μ μμ΅λλ€.
- μ°κ²°μ λκ±°λ μμμ λ°λ©νλ λ±μ νμ²λ¦¬ μμ μ μ§νν μ μμ΅λλ€.
- Cancelled
- νμ²λ¦¬ μμ κΉμ§ μλ£λλ©΄ λλ¬νλ μ΅μ’ μνμ λλ€.
μ½λ£¨ν΄ λΉλμ μ‘μ κ΄κ³
- μ½νλ¦° μ½λ£¨ν΄ λΌμ΄λΈλ¬λ¦¬μ λͺ¨λ μ½λ£¨ν΄ λΉλλ μμ λ§μ μ‘μ μμ±ν©λλ€.
- λλΆλΆμ μ½λ£¨ν΄ λΉλλ μ‘μ λ°ννλ©°, μ΄λ κ³³μμλ μ¬μ©ν μ μμ΅λλ€.
fun main(): Unit = runBlocking {
val job : Job = lauch {
delay(1000)
prinlnt("Test")
}
val deferred : Deferred<String> = async {
delay(1000)
"Test"
}
val job : Job = deferred
}
- launchμ λͺ μμ λ°ν νμ μ Jobμ΄λ©°, async ν¨μμ μν΄ λ°νλλ ν¨μλ Defferred<T>λ‘ μ΄ λν Job μΈν°νμ΄μ€λ₯Ό ꡬννκ³ μμ΅λλ€.
- λν Jobμ μ½λ£¨ν΄ 컨ν
μ€νΈμ΄λ―λ‘ coroutineContext[Job]μ μ¬μ©ν΄ μ κ·Όνλ κ²λ κ°λ₯ν©λλ€.
- μ΄λ νμ₯ νλ‘νΌν°λ₯Ό νμ©νλ κ²λ κ°λ₯ν©λλ€.
val CoroutineContext.job: Job
get() = get(Job) ?: error("Current context donsn't")
fun main(): Unit = runBlocking {
print(coroutineContext.job.isActive) // true
}
- μ‘μ λΆλͺ¨ - μμ κ΄κ³κ° μκΈ° λλ¬Έμ μ½λ£¨ν΄ μ€μ½ν λ΄μμ μ·¨μμ μμΈ μ²λ¦¬ ꡬνμ΄ κ°λ₯ν©λλ€.
fun main(): Unit = runBlocking {
val job: Job = launch { // μλμΌλ‘ λΆλͺ¨ μ‘μ μ¬μ©
delay(1000)
}
val parentJob: Job = coroutineContext.job // coroutineContext[Job]
println(job == parentJob) // false
val parentChildren: Sequence<Job> = parentJob.children
println(parentChildren.first() == job) // true
}
- μλ‘μ΄ Job 컨ν μ€νΈκ° λΆλͺ¨μ μ‘μ λ체νλ©΄ ꡬ쑰νλ λμμ±μ΄ μ ν¨νμ§ μμ΅λλ€.
fun main(): Unit = runBlocking {
launch(Job()) { // λΆλͺ¨μ‘μ μ¬μ©νμ§ μκ³ μλ‘ μμ±
delay(1000)
println("print?")
}
}
// μ무κ²λ μΆλ ₯λμ§ μκ³ μ’
λ£λ©λλ€.
- μ μ½λμμλ λΆλͺ¨ μμ μ¬μ΄μ μλ¬΄λ° κ΄κ³κ° μκΈ° λλ¬Έμ λΆλͺ¨κ° μμ μ½λ£¨ν΄μ κΈ°λ€λ¦¬μ§ μμ΅λλ€.
- μμμ μΈμλ‘ λ€μ΄μ¨ μ‘μ λΆλͺ¨λ‘ μ¬μ©νκΈ° λλ¬Έμ runBlockingκ³Ό μλ¬΄λ ¨ κ΄λ ¨μ΄ μκ² λ©λλ€.
- μ½ν¬ν΄μ΄ μμ λ§μ λ μμ μΈ μ‘μ κ°μ§κ³ μμΌλ©΄ λΆλͺ¨μ μλ¬΄λ ¨ κ΄λ ¨μ΄ μμΌλ©°, ꡬ쑰νλ λμμ±μ μκ² λ©λλ€.
μμλ€ κΈ°λ€λ¦¬κΈ°
- μ‘μ κ°μ₯ μ€μν μ΄μ μ μ½λ£¨ν΄μ΄ μλ£λ λκΉμ§ κΈ°λ€λ¦¬λ λ° μ¬μ©ν μ μλ€λ μ μ λλ€.
- μ΄λ₯Ό μν΄μ join λ©μλλ₯Ό νμ©ν©λλ€.
- joinμ μ§μ ν μ‘μ΄ Completedλ Cancelledμ κ°μ λ§μ§λ§ μνμ λλ¬ν λκΉμ§ κΈ°λ€λ¦¬λ μ€λ¨ ν¨μμ λλ€.
fun main(): Unit = runBlocking {
val job1 = launch {
delay(1000)
print("Test1")
}
val job2 = lauch {
delay(1000)
print("Test2")
}
job1.join()
job2.join()
print("all done")
}
// 1μ΄ ν .. Test1
// 1μ΄ ν .. Test2
// all done
- Job μΈν°νμ΄μ€λ λͺ¨λ μμμ μ°Έμ‘°ν μ μλ children νλ‘νΌν°λ₯Ό λ
ΈμΆμν΅λλ€.
- μ΄λ₯Ό νμ©ν΄μ λͺ¨λ μμμ΄ λ§μ§λ§ μνκ° λ λκΉμ§ κΈ°λ€λ¦΄ μ μμ΅λλ€.
val children = coroutineContext[Job]?.children
μ‘ ν©ν 리 ν¨μ
- Job() ν©ν 리 ν¨μλ₯Ό μ¬μ©νλ©΄ μ½λ£¨ν΄ μμ΄λ Jobμ μμ±ν μ μμ΅λλ€.
- μ΄λ€ μ½λ£¨ν΄κ³Όλ μ°κ΄λμ§ μμΌλ©°, 컨ν
μ€νΈλ‘ μ¬μ©ν μ μμ΅λλ€.
- μ΄λ ν κ° μ΄μμ μμ μ½λ£¨ν΄μ κ°μ§ λΆλͺ¨ μ‘μΌλ‘ μ¬μ©ν μλ μμ΅λλ€.
- νν μ€μ μ€ νλλ Job() ν©ν 리 ν¨μλ₯Ό μ¬μ©ν΄ μ‘μ μμ±νκ³ , λ€λ₯Έ μ½ν¬λ¦°μ λΆλͺ¨λ‘ μ§μ ν λ€μ joinμ νΈμΆνλ κ²μ
λλ€.
- μ΄λ μμ μ½λ£¨ν΄μ΄ λͺ¨λ μμ μ λλ§μ³λ Jobμ΄ μ¬μ ν μ‘ν°λΈ μνμ μκΈ° λλ¬Έμ νλ‘κ·Έλ¨μ΄ μ’ λ£λμ§ μμ΅λλ€.
suspend fun main() : Unit = coroutineScope {
val job = Job()
launch(job) { // μλ‘μ΄ μ‘μ΄ λΆλͺ¨λ‘λΆν¬μ΄ μμλ°μ μ‘μ λ체
delay(1000)
println("print")
}
launch(job) { // μλ‘μ΄ μ‘μ΄ λΆλͺ¨λ‘λΆν¬μ΄ μμλ°μ μ‘μ λ체
delay(2000)
println("print2")
}
job.join()
println("end?")
}
// 1μ΄ ν .. print
// 1μ΄ ν .. print2
// μμν μ€ν
- λ°λΌμ μ‘μ λͺ¨λ μμ μ½λ£¨ν΄μμ joinμ νΈμΆνλ κ²μ΄ λ°λμ§ν λ°©λ²μ λλ€.
job.children.forEach{ it.join() }
CompletableJob
- Jobμ νμ μΈν°νμ΄μ€λ‘, μλμ λ κ°μ§ λ©μλλ₯Ό κ°μ§λλ€.
- complete() : Boolean
- μ‘μ μλ£νλ λ° μ¬μ©νλ©°, λͺ¨λ μμ μ½λ£¨ν΄μ μμ μ΄ μλ£λ λκΉμ§ μ€ν μνλ₯Ό μ μ§νμ§λ§, completeλ₯Ό νΈμΆν μ‘μμ μλ‘μ΄ μ½λ£¨ν΄μ΄ μμλ μλ μμ΅λλ€.
- μ‘μ΄ μλ£λλ©΄ μ€ν κ²°κ³Όλ true, κ·Έλ μ§ μμ κ²½μ° falseκ° λ©λλ€.
fun main() = runBlocking {
val job = Job()
launch(job) {
repeat(3) { num ->
delay(200)
println("Rep$num")
}
}
launch {
delay(500)
job.complete()
}
job.join()
launch(job){ // jobμ΄ μλ£λμκΈ° λλ¬Έμ, μλ‘μ΄ μ½λ£¨ν΄μ μμνμ§ μμ
println("print")
}
println("Done")
}
// Rep0
// Rep1
// Rep2
// Done
- completeExceptionally(exception: Throwable): Boolean
- μΈμλ‘ λ°μ μμΈλ‘ μ‘μ μλ£μν΅λλ€.
- λͺ¨λ μμ μ½λ£¨ν΄μ μ£Όμ΄μ§ μμΈλ₯Ό λνν CancellationExceptionμΌλ‘ μ¦μ μ·¨μλ©λλ€.
fun main() = runBlocking {
val job = Job()
launch(job) {
repeat(3) { num ->
delay(200)
println("Rep$num")
}
}
launch {
delay(500)
job.completeExceptionally(Error("error"))
}
job.join()
launch(job){
println("print")
}
println("Done")
}
// Rep0
// Rep1
// Done
- 500μ΄μ completeExceptionally()λ₯Ό λ°μμμΌ°μΌλ―λ‘ Rep2λ μΆλ ₯λμ§ μμ΅λλ€.