#1 ์ด์ ๊ธ
[Kotlin] Coroutines - Coroutine builder
#1 Coroutine builder kotlinx-coroutines-core Core primitives to work with coroutines. Coroutine builder functions: Coroutine dispatchers implementing CoroutineDispatcher: More context elements: Synchronization primitives for coroutines: Top-level suspendin
kenel.tistory.com
ํด๋น ๊ฒ์๊ธ์ #2์์ ์ด์ด์ง๋ค.
import kotlinx.coroutines.*
fun main() {
println("Start")
runBlocking {
delay(5000) // 5์ด ๋๊ธฐ
}
println("End")
}
/* ์ถ๋ ฅ ๊ฒฐ๊ณผ
Start
End
*/
runBlocking์ ์ด๋ฆ์์ ๋ณด๋ฏ, ํ์ฌ ์ค๋ ๋๋ฅผ Blocking(๋ธ๋กํน)ํ๋ ํจ์๋ค. ๊ทธ๋ฆฌ๊ณ runBlocking { ... } ์์ญ ๋ด์ ์ฝ๋ฃจํด ์ฝ๋๋ฅผ ํ์ฌ ์ค๋ ๋์์ ์คํํ๋ค. runBlocking { ... }์ด ๋๋จ๊ณผ ๋์์ ํ์ฌ ์ค๋ ๋์ Blocking์ด ํด์ ๋๋ค. ์ ๋ฆฌํ๋ฉด, Blocking๋ ์ค๋ ๋์์ runBlocking { ... } ์ ์ฝ๋๋ง ์์ธ์ ์ผ๋ก ์คํํ๋ค. ๊ทธ๋ฌ๋ ์ฐ๋ฆฌ๊ฐ ์ฝ๋ฃจํด์ ์ฐ๋ ์ด์ ๋ฅผ ์๊ฐํด๋ณด๋ฉด ์ค๋ ๋๋ฅผ Blockingํด์ ์ ๋๋ค. ๋ณ๋ ฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๋ ค๊ณ Coroutine์ ์ฐ๋ ๊ฒ์ด๋ ๋ง์ด๋ค. ๊ฒ๋ค๊ฐ runBlocking๋ง ๋๋จธ์ง Coroutine builder(launch(), asycn(), produce())์ ๋ฌ๋ฆฌ CoroutineScope์ ํ์ฅ ํจ์๊ฐ ์๋๋ค. runBlocking์ ์ ์ฒด๋ ๋์ฒด ๋ฌด์์ธ๊ฐ?
#2 ์ฝ๋์ ๋๊ธฐ์ฑ ๋ฐ ๋น๋๊ธฐ์ฑ
[Kotlin] Coroutines - ๋๊ธฐ ์ฝ๋, ๋น๋๊ธฐ ์ฝ๋
#1 ๋๊ธฐ ์ฝ๋ vs ๋น๋๊ธฐ ์ฝ๋ #1-1 ๊ตฌ๋ถํ๊ธฐ ์ฝ๋ฃจํด์ ์ ๋๋ก ์ฌ์ฉํ๊ธฐ ์ํด์ ๋จผ์ , '๋๊ธฐ ์ฝ๋'์ '๋น๋๊ธฐ ์ฝ๋(= ์ฝ๋ฃจํด ์ฝ๋)'๋ฅผ ๋ช ํํ๊ฒ ๊ตฌ๋ถํ ์ค ์์์ผ ํ๋ค. ๋์ ๊ตฌ๋ถํ๋ ๊ธฐ์ค์ ์ฝ๊ฒ ๋ง
kenel.tistory.com
'๋๊ธฐ ์ฝ๋' ๋ฐ '๋น๋๊ธฐ ์ฝ๋'์ ๋ํ ๊ฐ๋
์ ์ฝ์ด์ผ ์ด ๋ค์์ ์ดํดํ ์ ์๋ค.
#3 runBlocking
#3-1 ์ ์ฒด

launch, async, produce๋ '๋น๋๊ธฐ ์ฝ๋'๋ฅผ '๋๊ธฐ ์ฝ๋'์ ์์ญ์ ๋ ์ ์๊ฒ ๋ง๋๋ ํฌ์ฅ์ง๋ค. ๋ฐ๋ฉด, runBlocking์ '๋น๋๊ธฐ ์ฝ๋'๋ฅผ '๋๊ธฐ ์ฝ๋'๋ก ๋ง๋๋ ํฌ์ฅ์ง๋ค. 1์ด ๊ธฐ๋ค๋ฆฌ๋ ๋์์ ์ํํ๋ delay(1000)์ด๋ผ๋ '๋น๋๊ธฐ ์ฝ๋'๋ฅผ ์๋ก ๋ค์ด ๋ณด๊ฒ ๋ค. ์ด ํจ์๋ฅผ '๋๊ธฐ ์ฝ๋'์ ์์ญ์ ๋ ์ ์๋ค. ์ด ์ธ์์ ๋ถ๊ฐ๋ฅ์ด๋ ์๋ค์ง๋ง, ์ ์ด๋ ์ฌ๊ธฐ์์ Kotlin ์ปดํ์ผ๋ฌ๊ฐ ํด์ง๋ฅผ ๋๊ธฐ์ ๋ถ๊ฐ๋ฅํ๋ค. ์ด ๋ runBlocking { ... }์ผ๋ก delay(1000)์ ๊ฐ์ธ๋ฉด, ์ปดํ์ผ๋ฌ๋์ด ํด๋น ์ฝ๋๋ฅผ ํ๋ฝํด์ค๋ค.
#3-2 ๋น๋๊ธฐ ์ฝ๋๊ฐ ๋๊ธฐ ์ฝ๋ ์์ญ์ ์กด์ฌํ ์ ์๋ ๊ธฐ์
#3-1์ '์ปดํ์ผ๋ฌ์ ํ๋ฝ'์ runBlocking์ด ํ์ฌ ์ค๋ ๋๋ฅผ Blocking(๋ธ๋กํน)ํ๋ค๋ ๊ฒ์ ๊ทผ๊ฑฐ๋ ํ๋ฝ์ด๋ค. ์ค๋ ๋๋ฅผ Block(๋ฉ์ถค)ํจ์ผ๋ก์จ runBlocking { ... }์ ์๊ณผ ๋ฐ์ '์์ฐจ์ฑ'์ ๋ถ์ฌํ๊ธฐ ๋๋ฌธ์ด๋ค. runBlocking์ด ์์๋๋ฉด(= '{' ๋ค๋ถํฐ) ํ์ฌ ์ค๋ ๋๊ฐ ๋ถ๋ถ์ ์ผ๋ก Blocking๋๋ค. ๋ฐ๋ผ์ runBlocking { ... } ์์ ๋ค์ด์ค๊ธฐ ์ ์ ์์
์ด runBlocking { ... } ๋ด์์ ์ํ๋์ง ์์ ๊ฒ์์ด ๋ณด์ฅ๋๋ค. ๋ถ๋ถ์ ์ผ๋ก Blocking๋๋ค๋ ๋ง์, runBlocking { ... } ๋ฐ์ ์๋ ๋ถ๋ถ์ด Blocking๋๋ค๋ ๊ฒ์ด๋ค. runBlocking { ... } ์์ ์๋ ์ฝ๋๋ค๋ง ์์ธ์ ์ผ๋ก ์คํ๋๋ค.
runBlocking์ด ๋๋๋ฉด(= '}'๋ฅผ ๋ง๋๋ฉด) ์ค๋ ๋์ ๊ฐํ์๋ ๋ถ๋ถ์ Blocking์ ํด์ ํด์ผ ํ๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ ์ ์ ์ํ๋๋ ๋์์ด ์๋ค. ๋ฐ๋ก, runBlocking ๋ด์ ๋ชจ๋ ์ฝ๋ฃจํด์ด ์ข
๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด๋ค. ์ฆ, join(), await(), receive() ๋ฐ์๊ฐ ์์์ ์ผ๋ก ์คํ๋๋ค๋ ์๊ธฐ๋ค. ๊ทธ๋์ผ runBlocking ๋ด๋ถ์ ์์
์ด runBlocking { ... } ๋ฐ์ ์๋ ์์
๊ณผ ๋์ ์คํ๋๋ค๊ฑฐ๋ ํ๋ ์ผ์ด ์์ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ์ฆ, runBlocking { ... } ๋ฐ์ด ๋๊ธฐ ์ฝ๋์ ์์ญ์์ ๋ณด์ฅํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ฌ ์ค๋ ๋์ ์
์ฅ์์ ๋ณด๋ฉด, ๋๊ธฐ ์ฝ๋ A โ B โ runBlocking { ... } โ E๊ฐ ์์ฐจ์ ์ด๋ฉฐ ์ฐ์์ ์ผ๋ก ์คํ๋๋ค. ์ค๋ ๋ ์
์ฅ์์ runBlocking { ... }์ด ๋๊ธฐ ์ฝ๋๋ก ๋ณด์ด๋ ๊ฒ์ด๋ค.
#3-3 runBlocking์ ์ฉ๋
runBlocking์ ์ค์ฉ์ฑ์ ๋ค๋ฅธ Coroutine builder๋ค์ ๋นํ๋ฉด ์์ด๋ณด์ธ๋ค. ์์ ๋งํ๋ฏ, ์ฐ๋ฆฌ๋ ๋ณ๋ ฌ ๊ตฌ์กฐ๋ฅผ ๋ง๋ค๋ ค๊ณ Coroutine์ ์ฐ๋ ๊ฒ์ด๋ ๋ง์ด๋ค. ๊ทธ๋์์ธ์ง, runBlocking์ ๋๋ถ๋ถ ์ฝ๋ ํ
์คํธ, ๋๋ฒ๊น
์ฉ๋๋ก ์ฐ์ธ๋ค๊ณ ํ๋ค. ๋๊ธฐ ์ฝ๋์ ์์ญ์ ํด์น์ง ์์ผ๋ฉด์ ๊ฐํธํ๊ฒ ์ฝ๋ฃจํด ์ฝ๋๋ฅผ ์ฌ์ฉํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
#3-4 ์ฌ๋ด
์ฌ๋ด์ผ๋ก, runBlocking๋ฅผ '๋น๋๊ธฐ ์ฝ๋ ์์ญ'์์ ์ฐ๋ ๊ฑด ์ธ ๋ฐ ์๋ ์ง์ด๋ค. ์๋ฌ๊ฐ ๋๋ ๊ฒ์ ์๋์ง๋ง, runBlocking์ ์ญํ ์ ์๊ฐํ๋ฉด ๋น์ฐํ๋ค. ๋๊ธฐ ์ฝ๋์ ์์ญ์ ๋น๋๊ธฐ ์ฝ๋๋ ์ฌ ์ ์์ง๋ง, ๋น๋๊ธฐ ์ฝ๋ ์์ญ์ ๋๊ธฐ ์ฝ๋๋ ์ผ๋ง๋ ์ง ํ์ฉ๋๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์, runBlocking์ ์ผ๋ฐ์ ์ผ๋ก '๋๊ธฐ ์ฝ๋์ ์์ญ'์์๋ง ์ฌ์ฉํ๋ ํจ์๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
#4 ์ฃผ์์
import kotlinx.coroutines.*
// ์ฝ๋ 1
fun main() {
println("main() is running on ${Thread.currentThread().name}")
runBlocking {
println("runBlocking is running on ${Thread.currentThread().name}")
launch {
delay(3000)
println("launch() is running on ${Thread.currentThread().name}")
}
}
// ...
}
/* โ โ โ ์ถ๋ ฅ ๊ฒฐ๊ณผ
main() is running on main
runBlocking is running on main
launch() is running on main
*/
---
// ์ฝ๋ 2
fun main() {
println("main() is running on ${Thread.currentThread().name}")
runBlocking {
println("runBlocking is running on ${Thread.currentThread().name}")
CoroutineScope(Dispatchers.Default).launch {
println("launch() is running on ${Thread.currentThread().name}")
}
}
// ...
}
/* โ โ โ ์ถ๋ ฅ ๊ฒฐ๊ณผ
main() is running on main
runBlocking is running on main
launch() is running on DefaultDispatcher-worker-1
*/
'์ฝ๋ 1'๊ณผ '์ฝ๋ 2'๋ ์๋ก ๋ค๋ฅธ ์ฝ๋๋ค. ์ถ๋ ฅ ๊ฒฐ๊ณผ๋ ์๋ก ๋ค๋ฅธ ๋ชจ์ต์ ๋ณด์ฌ์ค๋ค. ์ฝ๋ 1๊ณผ 2 ๋ชจ๋ runBlocking { ... }์ผ๋ก runBlocking์ด ์์นํ ์ค๋ ๋ (์ฌ๊ธฐ์๋ main()์ ์คํํ๋ ์ค๋ ๋(์ดํ ๋ฉ์ธ ์ค๋ ๋))์ ์๋์ Blockํ๋ค๋ ์ ์ ๊ฐ๋ค. ํ์ง๋ง ์ฝ๋ 1์ launch()๊ฐ runBlocking์ ์์์ผ๋ก์ ๋ฉ์ธ ์ค๋ ๋ํ์์ ์คํ๋๋ ๋ฐ๋ฉด, ์ฝ๋ 2์ launch()๋ ์๋ก์ด ์ฝ๋ฃจํด ์ค์ฝํ์์ ์๋ก์ด ์ค๋ ๋๋ฅผ ํ ๋น๋ฐ์ ์์ ํ ๋
๋ฆฝ์ ์ธ ์์
์ ์ํํ๋ค.
#5 ์์ฝ
์ค๋ ๋ ์ ์ฅ์์ runBlocking { ... }์ ๋๊ธฐ ์ฝ๋๋ก ๋ณด์ธ๋ค. ์ค์ ๋ก๋ ๊ทธ๋ ๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Kotlin' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Kotlin] Couroutine - ์ค๋ ๋(Thread)์ ์ค๋ ๋ ํ(Thread Pool) (1) | 2024.02.15 |
---|---|
[Kotlin] Coroutines - suspend ํค์๋ (0) | 2024.02.14 |
[Kotlin] Coroutines - Coroutine builder (0) | 2024.02.12 |
[Kotlin] Coroutines - CoroutineScope, CoroutineContext (1) | 2024.02.10 |
[Kotlin] Coroutines - Suspend vs Block (0) | 2024.02.09 |