Coroutine๊ณผ Thread

WellBeing-Manยท2021๋…„ 5์›” 5์ผ
1

๐Ÿ’ Coroutine์˜ ๋ชฉ์ 

๐Ÿ‘€ ๋ฐ”๋กœ Interleaving์„ ํ†ตํ•œ Concurrency ๋ณด์žฅ

  • Interleaving๊ณผ parallelizing

Thread์— Context switching๋งŒ์„ ํ†ตํ•ด Concurrency๋ฅผ ๋ณด์žฅํ•ด์ค๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ Coroutine์„ ์‚ฌ์šฉํ•˜๋ฉด ์ข€ ๋‹ค๋ฅด๋‹ค๋Š” ๋ฐ...

๋‘˜์„ ํ•œ๋ฒˆ ๋น„๊ตํ•ด ๋ณผ๊นŒ์š”?

๐Ÿ’ ์“ฐ๋ ˆ๋“œ์™€ ์ฝ”๋ฃจํ‹ด

๐Ÿ– ์“ฐ๋ ˆ๋“œ์˜ ์ž‘์—…์žฅ

์“ฐ๋ ˆ๋“œ

๊ฐ ์“ฐ๋ ˆ๋“œ๋งˆ๋‹ค task๋ฅผ ๊ฐ€์ง€๊ณ  ๊ฐ ์“ฐ๋ ˆ๋“œ๋Š” JVM Stack ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

๐Ÿ— ์ฝ”๋ฃจํ‹ด์˜ ์ž‘์—…์žฅ


์ฝ”๋ฃจํ‹ด์˜ Object๋Š” JVM Heap์— ์ ์žฌ๋˜๋ฉฐ, Context๋ฅผ ์“ฐ๋ ˆ๋“œ์—๊ฒŒ ์˜์กดํ•ฉ๋‹ˆ๋‹ค.(์ฝ”ํ‹€๋ฆฐ์˜ ์ฝ”๋ฃจํ‹ด์€ Stack์„ ๊ฐ€์ง€์ง€ ์•Š์ง€๋งŒ Stack์„ ๊ฐ€์ง€๋Š” ์ฝ”๋ฃจํ‹ด๋„ ์žˆ์Šต๋‹ˆ๋‹ค.)

๐Ÿ™ˆ context switch๋ฅผ ์–ผ๋งˆ๋‚˜ ํ•˜๊ธธ๋ž˜?

๐Ÿค” Thread case

๊ฐ ์“ฐ๋ ˆ๋“œ๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—, ๋งค ํ˜ธ์ถœ๋งˆ๋‹ค context switch๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


๋งŒ์ผ task1์—์„œ task2,task3 ํ˜ธ์ถœํ•˜๊ณ 
task4์—์„œ task5๋ฅผ ํ˜ธ์ถœ task5์—์„œ task6์„ ํ˜ธ์ถœ ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด
context switch๋Š” ์ด 4๋ฒˆ, ์“ฐ๋ ˆ๋“œ๋Š” 6๊ฐœ๊ฐ€ ํ•„์š”ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๐Ÿค” Coroutine case

์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ๊ฐ task๊ฐ€ ์ „ํ™˜ ๋ ๋•Œ๋งˆ๋‹ค context switching์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ฌ์ง€์–ด ๋ชจ๋‘ ํ•œ๊ฐœ์˜ ์“ฐ๋ ˆ๋“œ์—์„œ ์‹คํ–‰ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


์ด๋ ‡๊ฒŒ 0๋ฒˆ ์“ฐ๋ ˆ๋“œ์™€ 2๋ฒˆ ์“ฐ๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ ํ•  ์ˆ˜๋„ ์žˆ๊ณ , ๋งŒ์ผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ด๋„ context switch๋Š” 2๋ฒˆ์œผ๋กœ ๋๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ตญ Coroutine์€
context switching๋ฅผ ์ค„์ด๋ฉฐ, ๋” ์ ์€ ์“ฐ๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
์ฆ‰, ์“ฐ๋ ˆ๋“œ๋ฅผ ๋” ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๊ฒ ๋„ค์š”.

๐Ÿ’ ๊ฐ„๋‹จํ•œ ์‹คํ—˜

  • ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ• ๋•Œ ์‹คํ–‰ ์‹œ๊ฐ„
    ๋‹ค์Œ ์ฝ”๋“œ๋Š” ๊ฐ๊ฐ ์“ฐ๋ ˆ๋“œ์™€ ์ฝ”๋ฃจํ‹ด์—์„œ 1000๋ฒˆ์˜ task๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์“ฐ๋ ˆ๋“œ์™€ ์‹คํ–‰์‹œ๊ฐ„์„ ์ถœ๋ ฅํ•˜๋Š” ํ•จ์ˆ˜๋‹ค.
fun runInThread(){
    runBlocking {
        println("Active Thread = ${Thread.activeCount()}")
        val time = measureTimeMillis {
            val jobs = ArrayList<Thread>()
            ///rep = 1000
            repeat(reps) {
                jobs += Thread {
                    Thread.sleep(1000L)
                }.also { it.start() }
            }
            println("Active Thread = ${Thread.activeCount()}")
            jobs.forEach { it.join() }
        }
        println("Took $time ms\n")
    }
}
fun runInCoroutine() {
    runBlocking {
        println("Active Thread = ${Thread.activeCount()}")
        val time= measureTimeMillis {
            val jobs = ArrayList<Job>()
            ///rep = 1000
            repeat(reps){
                jobs+=launch(Dispatchers.Default){
                    delay(1000L)
                }
            }
            println("end, Active Thread= ${Thread.activeCount()}")
            jobs.forEach { it.join() }
        }
            println("Time: $time ms\n")
    }
}

์“ฐ๋ ˆ๋“œ์˜ ์ˆ˜๋„ ํ›จ์”ฌ ์ ์œผ๋ฉฐ, ์‹คํ–‰์‹œ๊ฐ„๋„ ํ›จ์”ฌ ๋‹จ์ถ• ๋˜์—ˆ๋„ค์š”. ์ฆ‰,
์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ๊ฐ€ ์ข€ ๋” ํšจ์œจ์ ์œผ๋กœ ์“ฐ๋ ˆ๋“œ๋ฅผ ํšจ์œจ์„ ๋†’ํž ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ™‡โ€โ™€๏ธ ์ถœ์ฒ˜

profile
๊ฑด๊ฐ•๋งจ

0๊ฐœ์˜ ๋Œ“๊ธ€