๋ณธ ๊ฒ์๊ธ์ #1 ~ #3์ ๋๊ธฐ์ฑ ๋ฐ ๋น๋๊ธฐ์ฑ์ ์ค๋ช ํ๊ธฐ ์ํด์ ์ค๋ ๋์ ๊ฐ๋ ์ ๋ํด ๊ณ ์์ ์ด๊ณ ๋ ผ๋ฆฌ์ ์ธ ๋น์ฝ์ ์ฌ์ฉํ๋ค. ์ด ๊ธ์ ๋ณด๋ ๋ถ์ ๊ผญ #4์ ์ฃผ์ํ ์ ๊น์ง ๋ด์ฃผ์ ์ผ ํ๋ค.
#1 ๋๊ธฐ ์ฝ๋ vs ๋น๋๊ธฐ ์ฝ๋
#1-1 ๊ตฌ๋ถํ๊ธฐ
์ฝ๋ฃจํด์ ์ ๋๋ก ์ฌ์ฉํ๊ธฐ ์ํด์ ๋จผ์ , '๋๊ธฐ ์ฝ๋'์ '๋น๋๊ธฐ ์ฝ๋(= ์ฝ๋ฃจํด ์ฝ๋)'๋ฅผ ๋ช ํํ๊ฒ ๊ตฌ๋ถํ ์ค ์์์ผ ํ๋ค. ๋์ ๊ตฌ๋ถํ๋ ๊ธฐ์ค์ ์ฝ๊ฒ ๋งํ์๋ฉด ์์ ์ด ์์ฐจ์ ์ผ๋ก ์คํ๋๋ ์ง์ ์ฌ๋ถ๋ค. ์์ฐจ์ ์ด๋ผ๋ ๊ฒ์, ์ด์ ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๋ค์ ์์ ์ด ์คํ๋์ง ์์์ ์๋ฏธํ๋ค. ๋น๋๊ธฐ ์ฝ๋๋ ๋๊ธฐ ์ฝ๋๊ฐ ์๋ ์ฝ๋๋ค.
#1-2 ๋น๋๊ธฐ ์ฝ๋์ ์์
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
suspend fun main() {
println("Start")
val myJob = CoroutineScope(Dispatchers.IO).launch {
println("Coroutine code start")
delay(2000)
println("Coroutine code end")
}
var meaninglessNumber = 0
for (i in 1..100000000) {
meaninglessNumber += i
}
println("End")
myJob.join()
}
/* ์ถ๋ ฅ ๊ฒฐ๊ณผ
Start
Coroutine code start
End
Coroutine code end
*/
์ ์ฝ๋์ '๋น๋๊ธฐ ์ฝ๋'๊ฐ ์กด์ฌํจ์ ๋ถ๋ช ํ๋ค. ์ฝ๋๊ฐ ์จ์ง ์์์ ์ถ๋ ฅ ๊ฒฐ๊ณผ๊ฐ ๋น๋กํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, ์์ฐจ์ ์ด์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
#2 ์ค๋ ๋์ ๋ณ๋ ฌ ๊ตฌ์กฐ
#2-1 ํ์ฐ์ ๋น(้)์์ฐจ์ฑ

์ด ์์ ๋์๋์์, ์๋ ์ค๋ ๋์ ์๋ A + B ์ถ๋ ฅ์ ๋ถ๊ฐ๋ฅํ๋ค. ํด๋น ์์ ์์ A์ ๊ธด ์์ ์๊ฐ ๋๋ฌธ์ ๊ทธ ๊ฐ์ด ๋ญ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค. ์ด์ ๊ฐ์ด ๋ณ๋ ฌ ๊ตฌ์กฐ๋ฅผ ๊ตฌ์ฑํ๋ฉด, ์์ฐจ๊ฐ ๋ ์ ๋ฐ์ ์๋ค. ๋ฌผ๋ก , ๋ง๋ฒ์ฒ๋ผ ๋ชจ๋ ํ์ด๋ฐ์ด ๋ฑ๋ฑ ๋ง์ ๋จ์ด์ง ์๋ ์๊ฒ ์ง๋ง, ๊ทธ๊ฑด ๋์ 100๊ฐ๋ฅผ ๋์ ธ์ ์ ๋ถ ์๋ฉด์ด ๋์ค์ง ์์ผ๋ฆฌ๋ ๋ฒ์ ์๋ค๋ ๋ง๊ณผ ๋๊ฐ์ ์๋ฆฌ๋ค. ์ฆ, ์ด๋ฌํ ์์ฐจ๋ ํ์ฐ์ ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ์์ฐจ๋ฅผ ๊ทน๋ณตํ๋ ค๋ฉด, ์์ง ์๋ฃ๋์ง ์์ ์ค๋ ๋๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํ๋ค. ๋ฉ์ถฐ(Suspend)์ผ ํ๋ค๋ ๋ง์ด๋ค.
#2-2 Suspend๋ฅผ ์ถ๊ฐํ ๋์๋

#2-1์ ์์ ํด Suspendํ๋ ์์ ์ ์ถ๊ฐํ๋ค.
#2-3 ๋น๋๊ธฐ ์ฝ๋์์ Suspend๊ฐ ์๋ ๊ฒฝ์ฐ

์ค๋ ๋ ๋ณ๋ ฌ ๊ตฌ์กฐ์์ Suspend๋ ๋ถ๋ช ํ์ฐ์ ์ด์ง๋ง, ํ์๋ ์๋๋ค. ์๋ฅผ ๋ค์ด, ์์ A์ B๋ฅผ ์ถ๋ ฅํ๋ ๊ฒ ์๋๋ผ ๊ทธ๋ฅ ๊ณ์ฐ๋ง ํ๊ณ ๋ง๋ ๊ฒฝ์ฐ๊ฐ ๊ทธ๋ ๋ค. ์์ฐจ๋ฅผ ๋ง์ถฐ์ ํ ์์ ์ด ์๋ค. ์ด๋ฐ ๊ฒฝ์ฐ์๋ ๊ตณ์ด Suspendํ์ง ์๋๋ค. ์ฆ, Suspend๋ ๋ณ๋ ฌ ๊ตฌ์กฐ์์ 'ํ์'ํ์ง๋ง, 'ํ์'๋ ์๋๋ผ๋ ์ด์ผ๊ธฐ๋ค.
#3 ๋๊ธฐ ์ฝ๋์ '์์ญ' vs ๋น๋๊ธฐ ์ฝ๋์ '์์ญ
๋๊ธฐ ์ฝ๋ ์์ญ์ ํ๋์ ์ค๋ ๋์์ ์์
์ด ์คํ๋๋ฉฐ, ์ด์ ์์
์ด ์๋ฃ๋ ๋๊น์ง ๋ค์ ์์
์ด ์คํ๋์ง ์๋ ํ๊ฒฝ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์ผ์์ ์ผ๋ก ์ ํด์จ ์ฝ๋์ ์ผ๋ฐ์ ์ธ ์์ญ์ด ๊ทธ๋ ๋ค. ๋ฐ๋๋ก ๋น๋๊ธฐ ์ฝ๋ ์์ญ์ ์์
๋ค์ด ์์ฐจ์ฑ ์์ด ๋ณ๋ ฌ์ ์ผ๋ก ์คํ๋ ์ ์๋ ํ๊ฒฝ์ ๋งํ๋ค. Coroutine์ ๋น๋๊ธฐ ์ฝ๋๋ฅผ ๊ตฌํํ ๋ ์ฐ ๋๊ตฌ์ง๋ง, Coroutine์ด๋ผ๊ณ ๋ฐ๋์ ๋น๋๊ธฐ ์ฝ๋์ธ ๊ฒ์ ์๋๋ค (์ฐธ์กฐ).
'๋๊ธฐ ์ฝ๋'์ ์์ญ์ '๋น๋๊ธฐ ์ฝ๋'๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์ด์งธ์? '๋น๋๊ธฐ ์ฝ๋'๋ ์ฝ๋๋ฅผ ์คํ(Run)ํ๋ ์ฃผ์ฒด์ธ ์์คํ
(Kotlin์ ๊ฒฝ์ฐ์ Kotlin ๋ฐํ์)์ '๊ธฐ๋'ํ๊ฒ ๋ง๋ค๊ธฐ ๋๋ฌธ์ด๋ค. ์์
์ด ๋น๋๊ธฐ์ ์ผ๋ก ์คํ๋๋ค๋ ์๊ธฐ๋ ์์คํ
์ด ์ธ์ ๊ทธ ์ฝ๋์ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์๋ณผ ์ ์๋ ์ง๋ฅผ ์ ์ ์๋ค๋ ์ด์ผ๊ธฐ๋ค. ์ฆ, '๋น๋๊ธฐ ์ฝ๋'๋ ์์คํ
์๊ฒ ๊ฐ์ ์ฆ๊ฐ์ ์ผ๋ก ๋ด์ฃผ์ง ์๋๋ค. ๋ฐ๋ผ์ ์์คํ
์ ์ธ์ ๊ฐ ์์
์ด ์๋ฃ(launch)๋๊ฑฐ๋ ๊ฐ์ ์ ๋ฌ(async, produce)ํด์ค ๊ฑฐ๋ผ๊ณ '๊ธฐ๋'๋ง ํ ์ ์๋ค. '๊ธฐ๋'๋ '๊ธฐ๋ค๋ฆผ'์ด๋ค. ๊ธฐ๋ค๋ฆผ์ '๊ฐํ์ ์ธ ๋ฉ์ถค'์ด๋ค. ๊ฐํ์ ์ผ๋ก ๋ฉ์ถ๋ ์ฝ๋๋ฅผ ์ด๋ป๊ฒ (์๋ฌ๊ฐ ๋์ง ์๋ ํ) ์ ๋ ๋ฉ์ถ์ง ์์์ ๋ณด์ฅํ๋ '๋๊ธฐ ์ฝ๋ ์์ญ'์ ๋ ์ ์๊ฒ ๋๊ฐ?
๋ฐ๋ฉด, '๋น๋๊ธฐ ์ฝ๋'์ ์์ญ์ '๋๊ธฐ ์ฝ๋'๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๋น๋๊ธฐ ์ฝ๋์ ์์ญ์ด๋ผ๊ณ ๋ฐ๋์ ๋น๋๊ธฐ ์ฝ๋๋ง ์์ ํ์๊ฐ ์๋ค. '๊ฐํ์ ๋ฉ์ถฐ์ง์ด ํ์ฉ๋๋ ๊ณณ'์ด์ง, '๋ฐ๋์ ๋ฉ์ถฐ์ผํ๋ ๊ณณ'์ด ์๋๊ธฐ ๋๋ฌธ์ด๋ค.
#1-2์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด, ๋น๋๊ธฐ ์ฝ๋๋ CoroutineScope๋ผ๋ ํฌ์ฅ์ง์ ๋๋ฌ์ธ์ฌ ๋ฐ์ ์๋ ๋๊ธฐ ์ฝ๋์ ์์ญ๊ณผ ๊ทธ ์์ญ์ด ๋ถ๋ช ํ ๊ตฌ๋ถ๋จ์ ๋ณผ ์ ์๋ค.
#4 ์ฃผ์ํ ์ (์ฝ๋ฃจํด์ ๋ฌผ๋ฆฌ์ ์ค๋ ๋๊ฐ ์๋๋ค)
#1 ~ #3์์๋ ๋๊ธฐ์ฑ ๋ฐ ๋น๋๊ธฐ์ฑ์ ์ค๋ช ํ๊ธฐ ์ํด์ ๋ง์น, ํ๋์ ์ฝ๋ฃจํด = ํ๋์ (๋ฌผ๋ฆฌ์ ) ์ค๋ ๋์ธ ๊ฒ์ฒ๋ผ ์ค๋ช ํ๋ค. ํ์ง๋ง, ์ด๋ ์ดํด๋ฅผ ์ํ ๊ณ ์์ ์ด๊ณ ๋ ผ๋ฆฌ์ ์ธ ๋น์ฝ์ด๋ค. ์ฆ ํ๋ฆฐ ์ค๋ช ์ด๋ค. ์ค๋ ๋(Thread)๋ ์ด์์ฒด์ ๊ฐ ๊ด๋ฆฌํ๋ ๊ฒ์ด๋ฉฐ ๊ฐ ์ค๋ ๋๋ ๋ฌผ๋ฆฌ์ ์ธ CPU์ ํ ๋น๋๋ค. ๋ฐ๋ฉด, ์ฝ๋ฃจํด์ ์ฝํ๋ฆฐ์ด๋ผ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด ๋จ์์์ ๊ด๋ฆฌ๋๋ ์ผ์ข ์ ๋ ผ๋ฆฌ์ ์ค๋ ๋๋ค.
์ฝ๋ฃจํด์ ๋ ผ๋ฆฌ์ ์ค๋ ๋์ด๊ธฐ์, ํ๋์ ๋ฌผ๋ฆฌ์ ์ค๋ ๋ ์์์ ์ฌ๋ฌ ๊ฐ์ ์ฝ๋ฃจํด์ด ์ํ๋ ์๋ ์๋ค. ์๋ฅผ ๋ค์ด, A๋ผ๋ ์ค๋ ๋์์ ์ฝ๋ฃจํด a์ ์ฝ๋ฃจํด b๊ฐ ์ํ๋๋ ์ํฉ์ด๋ผ๊ณ ๊ฐ์ ํด๋ณด๊ฒ ๋ค. a์ b๋ ์๋ก ์ ์ ๋ฉ์ถ(Suspend)๋ฉด์ ๋ค๋ฅธ ์ฝ๋ฃจํด์ด ์คํ๋ ์ ์๊ฒ ์์(A)์ ์๋ณดํ๋ ์์ด๋ค. ์ด ์๋ณด๋ฅผ ํตํด, ๊ฐ์ ์ค๋ ๋์์ ์ฌ๋ฌ ์ฝ๋ฃจํด์ด ๋ฒ๊ฐ์ ๊ฐ๋ฉฐ ์คํ๋จ์ผ๋ก์จ ๋ณ๋ ฌ์ ์ธ ๋์ ์คํ์ฒ๋ผ ๋ณด์ด๋ ๊ฒ์ ์ฝ๋ฃจํด์ ๋์์ฑ(Concurrency)์ด๋ผ๊ณ ํ๋ค. ์ด๋ ๋ฌผ๋ฆฌ์ ์ค๋ ๋์ ์ง์ง ๋์ ์คํ์ธ ๋ณ๋ ฌ์ฑ(Parallelism)๊ณผ ๋๋น๋๋ค.
ํ๋์ ์ฝ๋ฃจํด์ ํ๋์ ์ค๋ ๋์ ํ๋์ฉ ํ ๋นํ๋ ๊ฒ๋ ํ์ํ๋ค๋ฉด ๊ตฌํํ ์ ์๋ค. ์ค๋ ๋๊ฐ A, B, C ์ด 3๊ฐ๊ฐ ์์ ๋ ํ๋ก๊ทธ๋๋จธ๊ฐ CoroutineDispatcher๋ฅผ ์ด์ฉํด A, B, C ๊ฐ๊ฐ์ ํ๋์ ์ฝ๋ฃจํด์ ํ ๋นํ๋ฉด ๋๋ค (์ด๋ฌ๋ฉด ์ฝ๋ฃจํด์ Concurrency๊ฐ ์๋๋ผ Parallelism์ ๊ตฌํํ๊ฒ ๋๋ค). ์ฝ๋ฃจํด์ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ๋ ผ๋ฆฌ์ ์ค๋ ๋์ด์ง๋ง, ํ์ํ ๊ฒฝ์ฐ ์ค์ ๋ฌผ๋ฆฌ์ ์ค๋ ๋๊น์ง ๋ช ์ํด ์ฌ์ฉํ ์ ์๋ ์ ์ฐํ ๋๊ตฌ์ธ ์ ์ด๋ค.
#5 ์์ฝ
๋ณ๋ ฌ ๊ตฌ์กฐ๋ ํ์ฐ์ ์ผ๋ก ้์์ฐจ์ (้๋๊ธฐ์ )์ด๊ณ , ๋ฐ๋ผ์ Suspend๋ฅผ ์๊ตฌํ ์ ์๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Kotlin' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Kotlin] Coroutines - CoroutineScope, CoroutineContext (1) | 2024.02.10 |
---|---|
[Kotlin] Coroutines - Suspend vs Block (0) | 2024.02.09 |
[Kotlin] Coroutines - ๊ธฐ์ด (0) | 2024.02.07 |
[Kotlin] ๋๋ค(Lambda) ํํ์ (0) | 2024.02.01 |
[Kotlin] ํจ์ ํ์ (Fuction types) ํํ์ (0) | 2024.01.31 |