`launch` : ์์ ์คํ ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ์ง ์์
`async` : ์ฝ๋ฃจํด์ผ๋ก๋ถํฐ ๊ฒฐ๊ด๊ฐ์ ์์ → Deferred ๊ฐ์ฒด ๋ฐํ
async ์ฌ์ฉํด ๊ฒฐ๊ณผ๊ฐ ์์ ํ๊ธฐ
async ์ฌ์ฉํด Deferred ๋ง๋ค๊ธฐ
fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext, // CoroutineDispatcher ์ค์ ๊ฐ๋ฅ
start: CoroutineStart = CoroutineStart.DEFAULT, // ์ง์ฐ์์ ์ค์ ๊ฐ๋ฅ
block: suspend CoroutineScope.() -> T
): Deferred<T>
Deferred
- ์ฝ๋ฃจํด์ ์ถ์ํํ ๊ฐ์ฒด
- ์ฝ๋ฃจํด์ผ๋ก๋ถํฐ ์์ฑ๋ ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ์ธ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง
- ๊ฒฐ๊ณผ๊ฐ์ ํ์ ์ ์ ๋ค๋ฆญ ํ์ <T>
await๋ฅผ ์ฌ์ฉํ ๊ฒฐ๊ณผ๊ฐ ์์
`await()`
- ๊ฒฐ๊ณผ๊ฐ ์์ ์ ๋๊ธฐ๋ฅผ ์ํ ํจ์
- Deferred ์ฝ๋ฃจํด์ด ์คํ ์๋ฃ๋ ๋๊น์ง await() ๋ฅผ ํธ์ถํ ์ฝ๋ฃจํด ์ผ์ ์ค๋จ
- Deferred ์ฝ๋ฃจํด ์คํ์ด ์๋ฃ๋๋ฉด ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๊ณ ์ฝ๋ฃจํด ์ฌ๊ฐ
- Job ๊ฐ์ฒด์ join() ์ ์ ์ฌํ ๋์
fun main() = runBlocking<Unit> {
val networkDeferred: Deferred<String> = async(Dispatchers.IO) {
delay(1000L) // ๋คํธ์ํฌ ์์ฒญ
return@async "Dummy Response" // ๊ฒฐ๊ณผ๊ฐ ๋ฐํ
}
val result = networkDeferred.await() // networkDeferred๋ก๋ถํฐ ๊ฒฐ๊ณผ๊ฐ์ด ๋ฐํ๋ ๋๊น์ง runBlocking ์ผ์ ์ค๋จ
println(result) // Dummy Response ์ถ๋ ฅ
}
Deferred๋ ํน์ํ ํํ์ Job์ด๋ค
- Deferred ์ธํฐํ์ด์ค๋ Job ์ธํฐํ์ด์ค์ ์๋ธํ์
์ผ๋ก ์ ์ธ๋ ์ธํฐํ์ด์ค
→ ๊ฒฐ๊ณผ๊ฐ ์์ ์ ์ํด Job ๊ฐ์ฒด์ ๋ช๊ฐ์ง ๊ธฐ๋ฅ๋ง์ด ์ถ๊ฐ๋์ ๋ฟ - Job ๊ฐ์ฒด์ ๋ชจ๋ ํจ์์ ํ๋กํผํฐ๋ฅผ ์ฌ์ฉํ ์ ์์(join, cancle, …)
๋ณต์์ ์ฝ๋ฃจํด์ผ๋ก๋ถํฐ ๊ฒฐ๊ณผ๊ฐ ์์ ํ๊ธฐ
await๋ฅผ ์ฌ์ฉํด ๋ณต์์ ์ฝ๋ฃจํด์ผ๋ก๋ถํฐ ๊ฒฐ๊ณผ๊ฐ ์์ ํ๊ธฐ
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis() // 1. ์์ ์๊ฐ ๊ธฐ๋ก
val participantDeferred1: Deferred<Array<String>> = async(Dispatchers.IO) { // 2. ํ๋ซํผ1์์ ๋ฑ๋กํ ๊ด๋๊ฐ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ์ฝ๋ฃจํด
delay(1000L)
return@async arrayOf("James","Jason")
}
val participantDeferred2: Deferred<Array<String>> = async(Dispatchers.IO) { // 3. ํ๋ซํผ2์์ ๋ฑ๋กํ ๊ด๋๊ฐ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ์ฝ๋ฃจํด
delay(1000L)
return@async arrayOf("Jenny")
}
val participants1 = participantDeferred1.await() // 4. ๊ฒฐ๊ณผ๊ฐ ์์ ๋ ๋๊น์ง ๋๊ธฐ
val participants2 = participantDeferred2.await() // 5. ๊ฒฐ๊ณผ๊ฐ ์์ ๋ ๋๊น์ง ๋๊ธฐ
println("[${getElapsedTime(startTime)}] ์ฐธ์ฌ์ ๋ชฉ๋ก: ${listOf(*participants1, *participants2)}") // 6. ์ง๋ ์๊ฐ ๊ธฐ๋ก ๋ฐ ์ฐธ์ฌ์ ๋ชฉ๋ก ๋ณํฉ
}
- `participantDeferred1` ์ฝ๋ฃจํด ์คํ
- `participantDeferred2` ์ฝ๋ฃจํด ์คํ
- `participantDeferred1` ๊ฒฐ๊ณผ๊ฐ ๋๊ธฐ
- `participantDeferred2` ๊ฒฐ๊ณผ๊ฐ ๋๊ธฐ
โก๏ธ ์ฝ๋ฃจํด ๋๊ฐ๊ฐ ๋์์ ์คํ๋์ด ๋ชจ๋ ์ฝ๋ฃจํด์ด ์๋ฃ๋๊ธฐ๊น์ง 1์ด ์ ๋๋ง ์์
awaitAll์ ์ฌ์ฉํ ๊ฒฐ๊ณผ๊ฐ ์์
suspend fun <T> awaitAll(vararg deferred: Deferred<T>): List<T>
- ๊ฐ๋ณ์ธ์๋ก Deferred ํ์ ์ ๊ฐ์ฒด๋ฅผ ๋ฐ์ ์ธ์๋ก ๋ฐ์ ๋ชจ๋ ์ฝ๋ฃจํด์ผ๋ก๋ถํฐ ๊ฒฐ๊ณผ๊ฐ ์์ ๋ ๋๊น์ง ํธ์ถ๋ถ์ ์ฝ๋ฃจํด์ ์ผ์ ์ค๋จ
- ์์ ํ ๊ฒฐ๊ณผ๊ฐ๋ค์ List๋ก ๋ฐํ
fun main() = runBlocking<Unit> {
val startTime = System.currentTimeMillis() // 1. ์์ ์๊ฐ ๊ธฐ๋ก
val participantDeferred1: Deferred<Array<String>> = async(Dispatchers.IO) { // 2. ํ๋ซํผ1์์ ๋ฑ๋กํ ๊ด๋๊ฐ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ์ฝ๋ฃจํด
delay(1000L)
return@async arrayOf("James","Jason")
}
val participantDeferred2: Deferred<Array<String>> = async(Dispatchers.IO) { // 3. ํ๋ซํผ2์์ ๋ฑ๋กํ ๊ด๋๊ฐ ๋ชฉ๋ก์ ๊ฐ์ ธ์ค๋ ์ฝ๋ฃจํด
delay(1000L)
return@async arrayOf("Jenny")
}
val results: List<Array<String>> = awaitAll(participantDeferred1, participantDeferred2) // 4. ์์ฒญ์ด ๋๋ ๋๊น์ง ๋๊ธฐ
println("[${getElapsedTime(startTime)}] ์ฐธ์ฌ์ ๋ชฉ๋ก: ${listOf(*participants1, *participants2)}") // 6. ์ง๋ ์๊ฐ ๊ธฐ๋ก ๋ฐ ์ฐธ์ฌ์ ๋ชฉ๋ก ๋ณํฉ
}
- ์์ ์ฐ์๋ `await()` ์ฌ์ฉ๊ณผ ๋์ผํ ์ฒ๋ฆฌ ์์
withContext
withContext๋ก async-await ๋์ฒดํ๊ธฐ
`withContext()` : async-await ์์ ๋์ฒด
suspend fun <T> withContext(
context: CoroutineContext,
block: suspend CoroutineScope.() -> T
): T
- block ๋๋ค์์ ์คํํ๊ณ , ์๋ฃ๋๋ฉด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ก ๋ฐํ
- async-await ์์ ์ฐ์์ ์ผ๋ก ์คํํ์ ๋์ ๋์๊ณผ ๋น์ท
withContext ๋์ ๋ฐฉ์
- `async-await` : ์๋ก์ด ์ฝ๋ฃจํด์ ์์ฑํด ์์
์ ์ฒ๋ฆฌ
`withContext`: ์คํ์ค์ด๋ ์ฝ๋ฃจํด์ ๊ทธ๋๋ก ์ ์งํ ์ฑ๋ก ์ฝ๋ฃจํด์ ์คํ ํ๊ฒฝ๋ง ๋ณ๊ฒฝํด ์์ ์ฒ๋ฆฌ
fun main() = runBlocking<Unit> {
println("[${Thread.currentThread().name}] runBlocking ๋ธ๋ก ์คํ")
withContext(Dispatchers.IO) {
println("[${Thread.currentThread().name}] withContext ๋ธ๋ก ์คํ")
}
}
/*
// ๊ฒฐ๊ณผ:
[main @coroutine#1] runBlocking ๋ธ๋ก ์คํ
[DefaultDispatcher-worker-1 @coroutine#1] withContext ๋ธ๋ก ์คํ
*/
์คํํ๋ ์ค๋ ๋๋ ๋ค๋ฅด์ง๋ง, ์ฝ๋ฃจํด์ ๋์ผ → ๊ธฐ์กด์ ์ฝ๋ฃจํด์์ CoroutineContext ๊ฐ์ฒด๋ง ๋ฐ๊ฟ์ ์คํ
- ์ปจํ ์คํธ ์ค์์นญ: ์คํ ์ค์ธ ์ฝ๋ฃจํด์ ์คํ ํ๊ฒฝ์ด context ์ธ์๋ก ๋ณ๊ฒฝ๋์ด ์คํ
- block ๋๋ค์์ด ์คํ๋๋ ๋์ ์ฝ๋ฃจํด์ ์คํ ํ๊ฒฝ์ ๋ณ๊ฒฝ ( ๋๋ค์์ ๋ฒ์ด๋๋ฉด ์๋์ context ์ฌ์ฉ )
withContext ์ฌ์ฉ ์ ์ฃผ์์
๋ณต์์ ๋ ๋ฆฝ์ ์ธ ์์ ์ด ๋ณ๋ ฌ๋ก ์คํ๋์ด์ผ ํ๋ ์ํฉ์ ์ฑ๋ฅ ๋ฌธ์ ์ ๋ฐ
- async-await ์์ ์ฐ์์ ์ผ๋ก ์ฌ์ฉํ์ ๋์ ๋์ผํ ๋ฌธ์
- ํ๋์ ์ฝ๋ฃจํด์์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ณ๋ ฌ์ ์ผ๋ก ์คํ๋์ง ์๊ณ ์์ฐจ์ ์ผ๋ก ์คํ๋จ
http://www.acornpub.co.kr/book/kotlin-coroutines
์ฝํ๋ฆฐ ์ฝ๋ฃจํด์ ์ ์
๋ง์ ๊ฐ๋ฐ์๋ค์ด ์ด๋ ต๊ฒ ๋๋ผ๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋ค์ํ ์๊ฐ์ ์๋ฃ์ ์ค๋ช ์ ํตํด ๋๊ตฌ๋ ์ฝ๊ฒ ์ดํดํ ์ ์๋๋ก ์ฐ์ธ ์ฑ ์ด๋ค.
www.acornpub.co.kr
๐ํ๊ธฐ๐
Spring Boot - Kotlin ์ฌ์ฉํ๋ ํ๊ฒฝ์์ ์ฝ๋ฃจํด์ ๋ํ ๋ ๊น์ ์ง์์ด ํ์ํด ์ฐพ๋ค ๋ฐ๊ฒฌํ ์ฑ .
ํ๊ตญ์ธ ์ ์ ๋ถ์ด์ด์ ๊ทธ๋ฐ์ง ์ ๋ฐ์ ์ผ๋ก ์ดํดํ๊ธฐ ๊ต์ฅํ ์ฝ๊ฒ ๋์ด์๊ณ ,
๊ธฐ์กด ์ฝํ๋ฆฐ ์ฑ ์์๋ ์ฝ๊ฒ ๋ค๋ค์ง์ง ์๋ ๋ ๋ฅํ ์ฝ๋ฃจํด ๊ธฐ๋ฅ๊น์ง ์ ์ ์์.
(์ง๊ธ๊น์ง ์ฝ์ ๊ธฐ์ ์ ์ค ์ค๋ฌด์์ ๊ฐ์ฅ ์ ์ฐ๊ณ ์๋ ์ฑ ...๊ฐ์ฅ ์ ์ ์ฝํ ์ฑ ...๐)
SpringBoot-Kotlin ํ๊ฒฝ์์ ์ฝ๋ฃจํด์ ๋ ๊ณต๋ถํ๊ณ ์ถ๋ค๋ฉด ์ ๋ง ๊ฐ์ถ ํ์ ํ์ ๐๐ฅ๐๐ฅ๐๐ฅ๐๐ฅ๐๐ฅ
'๐ป ๊ฐ๋ฐ ์ผ์ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Flask] OpenAI Embedding์ ์ฌ์ฉํ ์ ์ฌ ๋ฌธ์ ๊ฒ์ (text-embedding-3-small) (0) | 2024.04.28 |
---|---|
OpenAI Embedding์ ์ฌ์ฉํ ์ ์ฌ ๋ฌธ์ ๊ฒ์ (Flask, ElasticSearch) (0) | 2023.10.22 |