lifecycle ?
์ก๊ณผ ๋ํผ๋
๋น๋๊ธฐ ํจ์๋ฅผ ๋ด๊ณผ ๊ฐ์ด ๋ ๊ทธ๋ฃน์ผ๋ก ๋๋ ๋ณผ ์ ์๋ค.
๊ฒฐ๊ณผ๊ฐ ์๋ ๋น๋๊ธฐ ํจ์ : ์ผ๋ฐ์ ์ธ ์๋๋ฆฌ์ค๋ ๋ก๊ทธ์ ๊ธฐ๋กํ๊ณ ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๋ ๊ฒ๊ณผ ๊ฐ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ๋ค ์ ์๋ค. ์๋ฃ ์ฌ๋ถ๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์์ง๋ง ๊ฒฐ๊ณผ๋ฅผ ๊ฐ์ง ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ด ์ด๋ฐ ์ ํ์ ์ํ๋ค.
๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๋น๋๊ธฐ ํจ์ : ์๋ฅผ ๋ค์ด ๋น๋๊ธฐ ํจ์๊ฐ ์น ์๋น์ค์์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ๋ ๊ฑฐ์ ๋๋ถ๋ถ ํด๋น ํจ์๋ฅผ ์ฌ์ฉํด ์ ๋ณด๋ฅผ ๋ฐํํ๊ณ ์ ํ ๊ฒ์ด๋ค.
์ก
์ก์ ํ์ด์ด-์ค-ํฌ๊ฒ(fire and forget)์์ ์ด๋ค. ํ ๋ฒ ์์๋ ์์ ์ ์์ธ๊ฐ ๋ฐ์ํ์ง ์๋ํ ๋๊ธฐํ์ง ์๋๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch {
// Do background task here
}
} ์์ธ ์ฒ๋ฆฌ
๊ธฐ๋ณธ์ ์ผ๋ก ์ก ๋ด๋ถ์์ ๋ฐ์ํ๋ ์์ธ๋ ์ก์ ์์ฑํ ๊ณณ๊น์ง ์ ํ๋๋ค. ์ก์ด ์๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ์ง ์์๋ ๋ฐ์ํ๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch {
// TODO("Not Implemented!")
}
delay(500)
} ์ด๋ ๊ฒ ํ๋ฉด ํ์ฌ ์ค๋ ๋์ ํฌ์ฐฉ๋์ง ์์ ์์ธ ์ฒ๋ฆฌ๊ธฐ์ ์์ธ๊ฐ ์ ํ๋๋ค.
๋ผ์ดํ ์ฌ์ดํด
๋ค์์ ์ก์ ๋ผ์ดํ ์ฌ์ดํด์ ๋ณด์ฌ์ฃผ๋ ๋ค์ด์ด๊ทธ๋จ์ด๋ค.
New(์์ฑ) : ์กด์ฌํ์ง๋ง ์์ง ์คํ๋์ง ์๋ ์ก
Active(ํ์ฑ) : ์คํ ์ค์ธ ์ก. ์ผ์ ์ค๋จ๋ ์ก๋ ํ์ฑ์ผ๋ก ๊ฐ์ฃผํ๋ค.
Completed(์๋ฃ ๋จ) : ์ก์ด ๋ ์ด์ ์คํ๋์ง ์๋ ๊ฒฝ์ฐ
Canceling(์ทจ์ ์ค) : ์คํ ์ค์ธ ์ก์์ cancel()์ด ํธ์ถ๋๋ฉด ์ทจ์๊ฐ ์๋ฃ๋ ๋๊น์ง ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ธฐ๋ ํ๋ค. ์ด๊ฒ์ ํ์ฑ๊ณผ ์ทจ์ ์ฌ์ด์ ์ค๊ฐ ์ํ๋ค.
Cancelled(์ทจ์ ๋จ) : ์ทจ์๋ก ์ธํด ์คํ์ด ์๋ฃ๋ ์ก. ์ทจ์๋ ์ก๋ ์๋ฃ๋ก ๊ฐ์ค๋ ์ ์๋ค.
์์ฑ
์ก์ ๊ธฐ๋ณธ์ ์ผ๋ก launch()๋ Job()์ ์ฌ์ฉํด ์์ฑ๋ ๋ ์๋์ผ๋ก ์์ํ๋ค. ์ก์ ์์ฑํ ๋ ์๋์ผ๋ก ์์๋์ง ์๊ฒ ํ๋ ค๋ฉด CoroutineStart.LAZY๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
// TODO("Not Implemented!")
}
delay(500)
} ํ์ฑ
์์ฑ ์ํ์ ์๋ ์ก์ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์์ํ ์ ์์ง๋ง ์ผ๋ฐ์ ์ผ๋ก start()๋ join()์ ํธ์ถํด์ ์คํํ๋๋ฐ, ๋์ ์ฐจ์ด์ ์ ์ ์์ ๊ฒฝ์ฐ ์ก์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ์ก์ ์์ํ๋ ๋ฐ๋ฉด ํ์๋ ์ก์ด ์๋ฃ๋ ๋๊น์ง ์คํ์ ์ผ์ ์ค๋จํ๋ค๋ ์ ์ด๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
// TODO("Not Implemented!")
}
job.start() // start๋ ์คํ์ ์ค๋จํ์ง ์์ผ๋ฏ๋ก suspend ํจ์๋ ์ฝ๋ฃจํด์์ ํธ์ถํ ํ์๊ฐ ์๋ค.
job.join() // join์ ์คํ์ ์ผ์ ์ค๋จํ ์ ์์ผ๋ฏ๋ก ์ฝ๋ฃจํด ๋๋ ์ผ์ ์ค๋จ ํจ์์ ํธ์ถํด์ผ ํ๋ค.
} ์ทจ์ ์ค
์ทจ์ ์์ฒญ์ ๋ฐ์ ํ์ฑ ์ก์ ์ทจ์ ์ค์ด๋ผ๊ณ ํ๋ ์คํ ์ด์ง ์ํ๋ก ๋ค์ด๊ฐ ์ ์๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
// TODO("Not Implemented!")
}
job.cancel()
job.cancel(cause = Exception("Timeout!")) // ์์ธ๊ฐ ์ทจ์์ ์์ธ์ผ ๋๋ ์์ธ์ ๊ฐ์ด ์ ๊ณตํด ์ฃผ๋ฉด ๋์ค์ ์ฐพ์๋ณผ ์ ์๋ค.
} ์ทจ์ ๋จ
์ทจ์ ๋๋ ์ฒ๋ฆฌ๋์ง ์์ ์์ธ๋ก ์ธํด ์คํ์ด ์ข ๋ฃ๋ ์ก์ ์ทจ์๋จ์ผ๋ก ๊ฐ์ฃผ๋๋ค. ์ก์ด ์ทจ์๋๋ฉด, getCancellationException() ํจ์๋ฅผ ํตํด ์ทจ์์ ๋ํ ์ ๋ณด๋ฅผ ์ป์ ์ ์๋ค.
fun main(args: Array<String>) = runBlocking {
val job = GlobalScope.launch(start = CoroutineStart.LAZY) {
// TODO("Not Implemented!")
}
job.cancel()
val cancellation = job.getCancellationException()
printf(cancellation.message)
}์ทจ์๋ ์ก๊ณผ ์์ธ๋ก ์ธํด ์คํจํ ์ก์ ๊ตฌ๋ณํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ด CoroutineExceptionHandler๋ฅผ ์ค์ ํด ์ทจ์ ์์ ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค.
fun main(args: Array<String>) = runBlocking {
val exceptionHandler = CoroutineExceptionHandler {
_: CoroutineContext, throwable: Throable ->
println("Job cancelled due to ${throwable.message}")
}
GlobalScope.launch(exceptionHandler) {
// TODO("Not Implemented!")
}
delay(2000)
}๋ค์๊ณผ ๊ฐ์ด invokeOnCompletion()์ ์ฌ์ฉํ ์๋ ์๋ค.
fun main(args: Array<String>) = runBlocking {
GlobalScope.launch {
// TODO("Not Implemented!")
}.invokeOnCompletion { cause ->
case?.let {
println("Job cancelled due to ${it.message}")
}
}
delay(2000)
}์ก์ ํ์ฌ ์ํ ํ์ธ
์ก์๋ ์ํ๊ฐ ๋ง์์ ์ธ๋ถ์์ ํ์ฌ ์ํ๋ฅผ ํ์ ํ๋ ๋ฐฉ๋ฒ์ ์์์ผ ํ๋ค.
isActive : ์ก์ด ํ์ฑ ์ํ์ธ์ง ์ฌ๋ถ. ์ก์ด ์ผ์ง ์ค์ง์ธ ๊ฒฝ์ฐ๋ true๋ฅผ ๋ฐํํ๋ค.
isCompleted : ์ก์ด ์คํ์ ์๋ฃํ๋์ง ์ฌ๋ถ
isCancelled : ์ก ์ทจ์ ์ฌ๋ถ. ์ทจ์๊ฐ ์์ฒญ๋๋ฉด ์ฆ์ true๊ฐ ๋๋ค.
์์ฑ ์ ๋ณด
์์ฑ๋จ(Created)
false
false
false
ํ์ฑ(Active)
true
false
false
์ทจ์์ค(Cancelling)
false
false
true
์ทจ์๋จ(Cancelled)
false
true
true
์๋ฃ๋จ(Completed)
false
true
false
๋ํผ๋
๋ํผ๋(Deffered)๋ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๋ ๋น๋๊ธฐ ์์ ์ ์ํํ๊ธฐ ์ํด ์ก์ ํ์ฅํ๋ค.
๋ค๋ฅธ ์ธ์ด์์๋ Future ๋๋ Promise๋ผ๊ณ ํ๋ ๊ฒ์ ์ฝํ๋ฆฐ ๊ตฌํ์ฒด๊ฐ ๋ํผ๋๋ค. ๊ธฐ๋ณธ์ ์ธ ์ฝ์ ํธ๋ ์ฐ์ฐ์ด ๊ฐ์ฒด๋ฅผ ๋ฐํํ ๊ฒ์ด๋ฉฐ, ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๋น์ด ์๋ค๋ ๊ฒ์ด๋ค.
fun main(args: Array<String>) = runBlocking {
val headlinesTask = GlobalScope.async {
getHealines
}
headlinesTask.await()
}์์ธ ์ฒ๋ฆฌ
์์ํ ์ก๊ณผ ๋ฌ๋ฆฌ ๋ํผ๋๋ ์ฒ๋ฆฌ๋์ง ์์ ์์ธ๋ฅผ ์๋์ผ๋ก ์ ํํ์ง ์๋๋ค. ๋ํผ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋๊ธฐํ ๊ฒ์ผ๋ก ์์ํ๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
fun main(args: Array<String>) = runBlocking {
val deffered = GlobalScope.async {
TODO("Not implemented yet!")
}
try {
headlinesTask.await()
} catch (throwable: Throable) {
println("Deferred cancelled due to ${throwable.message}")
}
}์์ฝ
์ก(Job)์ ์๋ฌด๊ฒ๋ ๋ฐํํ์ง ์๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ฌ์ฉ๋๋ค.
๋ํผ๋(Deferred)๋ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ด ์์ ํ๋ ค๋ ๊ฒ์ ๋ฐํํ ๋ ์ฌ์ฉ๋๋ค.
์ก์ ๋ค์ํ ์ํ๊ฐ์ ๊ฐ๋๋ค: ์์ฑ(New), ํ์ฑ(Active), ์ทจ์ ์ค(Canceling), ์ทจ์๋จ(Cancelled) ๋ฐ ์๋ฃ๋จ(Completed)
์ก์ ํ์ฌ ์ํ๋ฅผ ํ์ ํ๊ธฐ ์ํด isActive, isCancelled ๋ฐ isCompleted ์์ฑ์ ์ฌ์ฉํ ์ ์๋ค.
๋ํผ๋๋ ์ก์ ํ์ฅํด ๋ฌด์ธ๊ฐ๋ฅผ ๋ฐํํ ๊ฐ๋ฅ์ฑ์ ๋์ธ๋ค.
๋ํผ๋๊ฐ ๊ฐ์ง ์ ์๋ ์ํ๋ ์ก์ ์ํ์ ๊ฐ๋ค
์ก์ ์ํ๋ ์์ผ๋ก๋ง ์ด๋ํ ์ ์๋ค. ์ด์ ์ํ๋ก ๋๋๋ฆด ์ ์๋ค.
์ต์ข ์ํ(final states)๋ ์ก์ด ์ด๋ํ ์ ์๋ ์ํ ์ค ํ๋๋ค.
์ก์ ์ต์ข ์ํ๋ ์ทจ์๋จ(Cancelled) ๋ฐ ์๋ฃ๋จ(Completed)์ด๋ค.
join()์ ์ฌ์ฉํด ๋ํผ๋๊ฐ ๋๊ธฐ๋ ๊ฒฝ์ฐ, ์์ธ๊ฐ ์ ํ๋์ง ์๋๋ก ๊ฐ์ ์ฝ๊ธฐ ์ ์ ์ทจ์๋๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํด์ผ ํ๋ค.
ํญ์ ์ก์ ์์ธ๋ฅผ ๊ธฐ๋กํ๊ฑฐ๋ ํ์ํ์
Last updated