2024. 3. 13. 17:53, ๐ฑAndroid Study
๋ฐ์ํ
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ
- ๋๊ธฐ์ ํ๋ก๊ทธ๋๋ฐ : ์์๋๋ก ํ๋์ ์์
์ฉ ์ํํ๋ ํ์
- ์์ฐจ์ ์ผ๋ก ์ํํ๊ธฐ ๋๋ฌธ์ ์์ ์์ ์ ์ํฅ์ ๋ฐ์
- ์์ ์์ ์ด ๋๋์ง ์๋๋ค๋ฉด, ๋ค์ ์์ ์ ์์ํ ์ํํ ์ ์์
- ์์ฒญ์ ๋ณด๋ด๊ณ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ ๋๊น์ง ์์ ์ ๋ฉ์ถค - ๋ฐ๋ผ์ ๊ผญ ๋๊ธฐ์ ์ผ๋ก ์คํํ์ง ์์๋ ๋๋ ๊ธฐ๋ฅ์ ๋น๋๊ธฐ์ ์ผ๋ก ์คํํ๋๊ฒ ์ข์
- ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ: ์ฌ๋ฌ๊ฐ์ง์ ๋ก์ง๋ค์ด ์๋ฃ ์ฌ๋ถ์ ๊ด๊ณ์์ด ์คํ๋๋ ๋ฐฉ์
- ์์ฒญ์ ๋ณด๋ด๊ณ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐ์ง ์์๋ ๋ฉ์ถ์ง ์๊ณ ๋ ๋ค๋ฅธ ์ผ์ ์ํ
- ์: 5GB ์์ ๋ค์ด๋ก๋ → ๋ฉ์ผ์ ์ก → ์๋ฆผ์ ์์๋ฅผ ๊ฐ์ง ๋ก์ง
- ๋๊ธฐ์ ์ผ๋ก ์งํํ๋ค๋ฉด ๋ค์ด๋ก๋ ์ค ๋ค๋ฅธ ์์ ์ ํ์ง๋ชปํ๊ณ ์ฑ์ด ๋ฉ์ถ๋ ๋ฑ์ ๋ฌธ์ ๋ฐ์
- ๋ฐ๋ผ์ ๋น๋๊ธฐ์ ์ผ๋ก, ๋ค๋ฅธ ์์ ์ ํ๊ณ ์๋ค๊ฐ ์์ ๋ค์ด๋ก๋๊ฐ ์๋ฃ๋์๋ ์๋ฆผ์ด ๋ฐ์ํ๋ ๊ฒ์ด ์ข์
์ฐ๋ ๋ (Thread)
- ํ๋ก๊ทธ๋จ์ ํ๋์ ๋ฉ์ธ ์ฐ๋ ๋(์คํํ๋ฆ)๊ฐ ์กด์ฌ
- ๋ฉ์ธ ์ฐ๋ ๋: fun main() ←— ๋ฉ์ธํจ์
- ๋ฉ์ธ ์ฐ๋ ๋ ์์์ ๋ก์ง์ ์คํํ๋ฉด ๋์์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅ
- ๋ฐ๋ผ์ thread ํค์๋๋ก, ๋ณ๋์ ์์ ์ฐ๋ ๋๋ฅผ ์์ฑํด์ ๋์์ ๋ก์ง์ ์คํ
- ์ฐ๋ ๋๊ฐ ํ์ํ ๊ฒฝ์ฐ ์์
(1) ๋ชฌ์คํฐ๋ฅผ ๊ณต๊ฒฉ / ์ฒด๋ ฅ ๋ณ์ / ํจ๊ณผ์ ๋ฐ์ 3๊ฐ๊ฐ ๋์์ ๋ฐ์ํด์ผ ํ๋ ๊ฒฝ์ฐ
(2) ๊ฒฝ๋ง ํ๋ก๊ทธ๋จ์ ๋ง๋ค์ด ๋์์ ์ถ๋ฐํด์ ๊ฒฝ์ํด์ผ ํ๋ ๊ฒฝ์ฐ
ํ๋ก์ธ์ค์ ์ค๋ ๋์ ์ฐจ์ด
ํ๋ก์ธ์ค(Process)
- ํ๋ก๊ทธ๋จ์ด ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ์ ์คํ๋ ๋, ํ๋ก์ธ์ค 1๊ฐ
- ๋ณดํต ํ๋ก๊ทธ๋จ์ ๋๋ธํด๋ฆญํ๋ฉด ํ๋ก์ธ์ค๊ฐ ์๊น
์ฐ๋ ๋(Thread)
- ์ฐ๋ ๋๋ ํ๋ก์ธ์ค๋ณด๋ค ๋ ์์ ๋จ์ (ํ๋ก์ธ์ค ์์์ ๋ ์์ ์์ ์ ๋จ์ = ์ฐ๋ ๋)
- ์ฐ๋ ๋๋ ์์ฑ๋์ ์ํํ ๋ ๊ฐ ๋ ๋ฆฝ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ธ STACK ์ ๊ฐ์ง
- ์ฆ ์ฐ๋ ๋๋ฅผ ํ ๊ฐ ์์ฑํ๋ฉด ์คํ๋ฉ๋ชจ๋ฆฌ์ ์ผ์ ์์ญ์ ์ฐจ์ง
์ฌ์ฉ ์์
// ์ฝ๋ฃจํด ์ฝ์
ํ ๋นจ๊ฐ ๋ถ๋ถ ํด๋ฆญํ๊ณ import ํด์ฃผ๋ฉด ๋จ
fun main() {
thread(start = true) { // 1๋ถํฐ 10๊น์ง ์ถ๋ ฅํ๋ ์ฝ๋๋ฅผ 2๊ฐ์ ์ฐ๋ ๋๋ก ๊ฒฝ์
for(i in 1..10) {
println("Thread1: ํ์ฌ ์ซ์๋ ${i}")
runBlocking {
launch {
delay(1000) // 1์ด๋ง๋ค ์์๊ฒฝ์์ ์ํค๊ธฐ ์ํด ๋๋ ์ด ์ถ๊ฐ
}
}
}
}
thread(start = true) {
for(i in 50..60) {
println("Thread2: ํ์ฌ ์ซ์๋ ${i}")
runBlocking {
launch {
delay(1000)
}
}
}
}
}
// Thread1๊ณผ Thread2์ ์์๋ ๋ณด์ฅ๋์ง ์๊ณ ๊ฒฝ์
- ์ค๋ ๋ ์ฌ์ ์์ : ์ธ๋ถ ์ข ์์ฑ ์ถ๊ฐ (https://github.com/Kotlin/kotlinx.coroutines#android)
- build.gradle์ implementation ์ฝ๋ฃจํด ์ ์ฉ
์ฝ๋ฃจํด (Coroutine)
- ์ฝ๋ฃจํด์ ์ ์: ๊ณต์๋ฌธ์ (๋งํฌ)
- ์ฐ๋ ๋๋ณด๋ค ๋์ฑ ๊ฒฝ๋ํ๋์ด ๊ฐ๋ณ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋น๋๊ธฐ ๊ธฐ๋ฅ
- ์ต์ ํ๋ ๋น๋๊ธฐ ํจ์๋ฅผ ์ฌ์ฉ
- ํ๋์จ์ด ์์์ ํจ์จ์ ์ธ ํ ๋น, ์์ ์ ์ธ ๋์์ฑ
- ๋ก์ง๋ค์ ํ๋ํด์ ์คํํ์๋๊ฒ ๋ชฉํ์ด๋ฉฐ ๊ตฌ๊ธ์์ ์ ๊ทน ๊ถ์ฅ
- ์ฝ๋ฃจํด์ ๋น๋์ ํจ๊ป ์ฌ์ฉ
์ฝ๋ฃจํด ๋น๋์ ์ข ๋ฅ : launch (๊ฒฐ๊ณผ๊ฐ X), async (๊ฒฐ๊ณผ๊ฐ O)
- launch๋ Job ๊ฐ์ฒด๋ก ์ฝ๋ฃจํด์ ๊ด๋ฆฌํ๋๋ฐ, Job๊ฐ์ฒด๋ ๋ค์ํ ํจ์๋ฅผ ๊ฐ์ง๊ณ ์์
- join: ํ์ฌ์ ์ฝ๋ฃจํด์ด ์ข ๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆผ
- cancel: ํ์ฌ์ ์ฝ๋ฃจํด์ ์ฆ์ ์ข ๋ฃ
- ์ฝ๋ฃจํด์ ์ค์ฝํ๋ก ๋ฒ์๋ฅผ ์ง์ ํ ์ ์์
- GlobalScope: ์ฑ์ด ์คํ๋ ์ดํ์ ๊ณ์ ์ํ๋์ด์ผํ ๋ ์ฌ์ฉ (์ฌ์ฉ ํ ์ ๋ฆฌ X)
- CoroutineScope: ํ์ํ ๋๋ง ์์์ ์ผ๋ก ์์ฑ (์ฌ์ฉ ํ ์ ๋ฆฌ ํ์ O)
- Dispatcher๋ก ์ฝ๋ฃจํด์ ์คํํ ์ฐ๋ ๋๋ฅผ ์ง์ ํ ์ ์์ (ํ๋์ ์ฐ๋ ๋ ์์ ์ฌ๋ฌ ๊ฐ์ ์ฝ๋ฃจํด)
- Dispatchers.Main: UI์ ์ํธ์์ฉํ๊ธฐ ์ํ ๋ฉ์ธ์ฐ๋ ๋
- Dispatchers.IO: ๋คํธ์ํฌ๋ ๋์คํฌ I/O์์ ์ ์ต์ ํ๋์ด์๋ ์ฐ๋ ๋
- Dispatchers.Default: ๊ธฐ๋ณธ์ ์ผ๋ก CPU์ต์ ํ๋์ด์๋ ์ฐ๋ ๋
- ์๋๋ก์ด๋์์๋ ํนํ Dispatcher๊ฐ์ ๋ณํ์ ํด์ผํ๋ ์์ ์ ๊ณ ๋ คํด์ผํจ
์ค์ต ํ๊ฒฝ ์ค์
fun main(args: Array<String>) {
println("๋ฉ์ธ์ฐ๋ ๋ ์์")
var job = GlobalScope.launch {
delay(3000) // delay 3์ด๋ฅผ ์ฃผ์์ง๋ง, main ํจ์์์ "๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ" ๋จผ์ ์ถ๋ ฅ๋๊ณ ๋๋๋ฒ๋ฆผ
println("์ฌ๊ธฐ๋ ์ฝ๋ฃจํด...")
}
println("๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ")
}
- ์๋๋ก์ด๋๋ ํญ์ ์ฑ์ด ์ผ์๋ ์ํ์ง๋ง, ์ค์ตํ๊ฒฝ์ kt ํ์ผ์ ์ด์ฉํด ์คํ ํ ์ข ๋ฃ๋๋ JVMํ๊ฒฝ
- ๋ฐ๋ผ์ ์คํํ๋ฉด main์ด ๋จผ์ ์ข ๋ฃ๋๊ธฐ ๋๋ฌธ์ 3์ด ๋ค ์ถ๋ ฅํด์ผ ํ๋ ์ฝ๋ฃจํด์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์์
// ๊ธ๋ก๋ฒ ์ค์ฝํ ํ์ฉ
fun main(args: Array<String>) {
println("๋ฉ์ธ์ฐ๋ ๋ ์์")
var job = GlobalScope.launch {
delay(3000)
println("์ฌ๊ธฐ๋ ์ฝ๋ฃจํด...")
}
runBlocking { // ์๋ job์ด ์คํ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ๊ฒ ๋ค ๋ช
์
job.join()
}
println("๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ") // job.join() ์คํ ๋ค์ ์ถ๋ ฅ ํ ์ข
๋ฃ
}
// ์ฝ๋ฃจํด ์ค์ฝํ ํ์ฉ
fun main(args: Array<String>) {
println("๋ฉ์ธ์ฐ๋ ๋ ์์")
var job = CoroutineScope(Dispatchers.Default).launch {
delay(3000)
println("์ฌ๊ธฐ๋ ์ฝ๋ฃจํด...")
}
runBlocking {
job.join()
}
println("๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ")
job.cancel() // ์ฝ๋ฃจํด์ค์ฝํ๋ ์์๋ก ์ฌ์ฉํ ๊ฑฐ๋ผ, ์ฌ์ฉ ํ ํด์ ํด์ผ ํจ
}
- ์ค์ตํ๊ฒฝ์์ ๋๊ธฐ์ ์ผ๋ก ์ฝ๋ฃจํด์ ๊ฒฐ๊ณผ๋ฅผ ์กฐํํ๊ณ ์ถ๋ค๋ฉด job์ join๋ฉ์๋๋ฅผ ํ์ฉ
- ์๋๋ก์ด๋์ ๋ฌ๋ฆฌ ์ฑ์ด ํญ์ ์ผ์ ธ์์ง ์๊ธฐ ๋๋ฌธ์ job์ผ๋ก ์ค์ต์ ์งํ
์ฝ๋ฃจํด ์ฌ์ฉ ์์
println("๋ฉ์ธ์ฐ๋ ๋ ์์")
var job = CoroutineScope(Dispatchers.Default).launch {
var fileDownloadCoroutine = async(Dispatchers.IO) { // async ์ด์ฉ, 10์ด
delay(10000)
"ํ์ผ ๋ค์ด๋ก๋ ์๋ฃ"
}
var databaseConnectCoroutine = async(Dispatchers.IO) {
delay(5000)
"๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์๋ฃ" // async ์ด์ฉ, 5์ด
}
println("${fileDownloadCoroutine.await()}")
println("${databaseConnectCoroutine.await()}")
}
runBlocking {
job.join()
}
println("๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ") // ๋ฉ์ธ์ฐ๋ ๋ ์์, (10์ด ๋ค ํ ๋ฒ์) ํ์ผ ๋ค์ด๋ก๋ ์๋ฃ, ์ฐ๊ฒฐ ์๋ฃ, ๋ฉ์ธ์ฐ๋ ๋ ์ข
๋ฃ
job.cancel()
- ์ฌ๋ฌ ๊ฐ์ ์ฝ๋ฃจํด์ ์์ ๊ฐ์ด ์ฌ์ฉ ๊ฐ๋ฅํจ
- ์ฝ๋ฃจํด์ ๊ฒฐ๊ณผ๊ด์ ๋ฆฌํด ๋ฐ์ ์ ์์
- ๊ฒฐ๊ณผ ๊ฐ์ ๋ฆฌํด ๋ฐ์์ผํ๊ธฐ ๋๋ฌธ์, await๋ ์ผ์์ค๋จ์ด ๊ฐ๋ฅํ ์ฝ๋ฃจํด์์ ์คํ ๊ฐ๋ฅ
์ฐ๋ ๋์ ์ฝ๋ฃจํด ๋น๊ต
- ๋ ๋ค ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๊ธฐ์
- ๋์์ฑ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ์ ์ ์ปจํ ์คํธ ์ค์์นญ(๋ฌธ๋งฅ ๊ตํ)์ด ์ค์ํ ๊ฐ๋ (๋งํฌ)
- ์ฝ๋ฃจํด์ ์ฐ๋ ๋๋ฅผ ๋์ฒดํ๋ ๊ธฐ์ ์ด ์๋๋ฉฐ, ํ๋์ ์ฐ๋ ๋๋ฅผ ๋์ฑ ์๊ฐ ์ชผ๊ฐ์ ์ฌ์ฉํ๋ ๊ฒ (๊ฐ์์ ๋ฐฉ๋ฒ์ด ๋ค๋ฆ)
- ์ฝ๋ฃจํด์ ์ฐ๋ ๋๋ณด๋ค CPU์์์ ์ ์ฝํ๊ธฐ ๋๋ฌธ์ Light-Weight Thread๋ผ๊ณ ๋ ๋ถ๋ฆผ
- ๊ตฌ๊ธ์์๋ ์ฝํ๋ฆฐ์ ์ฝ๋ฃจํด ์ฌ์ฉ์ ์ ๊ทน ๊ถ์ฅ
์ฐ๋ ๋
- ์์
ํ๋ํ๋์ ๋จ์ : Thread
- ๊ฐ Thread ๊ฐ ๋ ๋ฆฝ์ ์ธ Stack ๋ฉ๋ชจ๋ฆฌ ์์ญ์ ๊ฐ์ง
- ๋์์ฑ ๋ณด์ฅ ์๋จ : Context Switching
- ์ด์์ฒด์ ์ปค๋์ ์ํ Context Switching ์ ํตํด ๋์์ฑ์ ๋ณด์ฅ
- ๋ธ๋กํน (Blocking)
- Thread A๊ฐ Thread B ์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ์ค
- ์ด ๋, Thread A๋ ๋ธ๋กํน ์ํ๋ผ๊ณ ํ ์ ์์
- A๋ Thread B ์ ๊ฒฐ๊ณผ๊ฐ ๋์ฌ ๋ ๊น์ง ํด๋น ์์์ ์ฌ์ฉํ์ง ๋ชปํจ
- Thread A๊ฐ Task 1์ ์ํํ๋ ๋์ Task 2 ์ ๊ฒฐ๊ณผ๊ฐ ํ์ํ๋ฉด Thread B๋ฅผ ํธ์ถ
- ์ด๋ Thread A๋ ๋ธ๋กํน ๋๊ณ Thread B๋ก ํ๋ก์ธ์ค๊ฐ์ ์ค์์นญ์ด ์ผ์ด๋ Task 2์ ์ํ
- Task 2๊ฐ ์๋ฃ๋๋ฉด Thead A๋ก ๋ค์ ์ค์์นญํด์ ๊ฒฐ๊ณผ ๊ฐ์ Task 1์๊ฒ ๋ฐํ
- ์ด๋ Task 3, Task 4๋ A, B์์ ์ด ์งํ๋๋ ๋์ค์ ๋ฉ์ถ์ง ์๊ณ ๊ฐ๊ฐ ๋์์ ์คํ๋จ
- ์ด๋ ์ปดํจํฐ ์ด์์ฒด์ ์ ์ฅ์์๋ ๊ฐ Task๋ฅผ ์ชผ๊ฐ์ ์ผ๋ง๋ ์ํํ ์ง๊ฐ ์ค์
- ๊ทธ๋์ ์ด๋ค ์ฐ๋ ๋๋ฅผ ๋จผ์ ์คํํด์ผํ ์ง ๊ฒฐ์ ํ๋ ํ์๋ฅผ ์ค์ผ์ฅด๋ง์ด๋ผ๊ณ ํจ
- ์ด๋ฌํ ํ์๋ฅผ ํตํด ๋์์ฑ์ ๋ณด์ฅ
์ฝ๋ฃจํด
- ์์
ํ๋ํ๋์ ๋จ์ : Coroutine Object
- ์ฌ๋ฌ ์์ ๊ฐ๊ฐ์ Object ๋ฅผ ํ ๋น
- Coroutine Object ๋ ์์ฐํ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ JVM Heap ์ ์ ์ฌ (์ฝํ๋ฆฐ ๊ธฐ์ค)
- ๋์์ฑ ๋ณด์ฅ ์๋จ : Programmer Switching (No-Context Switching)
- ์์ค ์ฝ๋๋ฅผ ํตํด Switching ์์ ์ ๋ง์๋๋ก ์ ํจ (OS๋ ๊ด์ฌํ์ง ์์)
- Suspend (Non-Blocking)
- Object 1์ด Object 2์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆด ๋ Object 1์ ์ํ๋ Suspend๋ก ๋ฐ๋
- ๊ทธ๋๋ Object 1์ ์ํํ๋ Thread๋ ๊ทธ๋๋ก ์ ํจ
- ๊ทธ๋์ Object 2๋ Object 1๊ณผ ๋์ผํ Thread์์ ์คํ
- Task 1์ ์ํํ๋ค๊ฐ Task 2์ ์ํ์์ฒญ์ด ๋ฐ์ํ๋ค๊ณ ๊ฐ์
- ์ ๊ธฐํ๊ฒ๋ ์ปจํ ์คํธ ์ค์์นญ ์์ด ๋์ผํ Thread A์์ ์ํํ ์ ์์
- Thread C์ฒ๋ผ ํ๋์ ์ฐ๋ ๋์์ ์ฌ๋ฌ Task Object๋ค์ ๋์์ ์ํํ ์ ์์
- ์ด๋ฌํ ํน์ง๋๋ฌธ์ ์ฝ๋ฃจํด์ Light-Weight Thread๋ผ๊ณ ๋ถ๋ฆ
๋ฐ์ํ
๐ฌ C O M M E N T