Skip to the content.

스코프 빌더, 잡

예제 10: suspend 함수에서 코루틴 빌더 호출

코루틴 빌더를 suspend 함수 안에서 호출하면 어떻게 될까요?

import kotlinx.coroutines.* suspend fun doOneTwoThree() { launch { println("launch1: ${Thread.currentThread().name}") delay(1000L) println("3!") } launch { println("launch2: ${Thread.currentThread().name}") println("1!") } launch { println("launch3: ${Thread.currentThread().name}") delay(500L) println("2!") } println("4!") } fun main() = runBlocking { doOneTwoThree() println("runBlocking: ${Thread.currentThread().name}") println("5!") }

코루틴 빌더는 코루틴 스코프 내에서만 호출해야 합니다.

예제 11: 코루틴 스코프

코루틴 스코프를 만드는 다른 방법은 스코프 빌더를 이용하는 것입니다. coroutineScope를 이용해보세요.

import kotlinx.coroutines.* suspend fun doOneTwoThree() = coroutineScope { launch { println("launch1: ${Thread.currentThread().name}") delay(1000L) println("3!") } launch { println("launch2: ${Thread.currentThread().name}") println("1!") } launch { println("launch3: ${Thread.currentThread().name}") delay(500L) println("2!") } println("4!") } fun main() = runBlocking { doOneTwoThree() println("runBlocking: ${Thread.currentThread().name}") println("5!") }

코루틴 스코프는 runBlocking을 썼을 때와 모양이 거의 비슷합니다.

하지만 둘의 차이가 있는데 runBlocking은 현재 쓰레드를 멈추게 만들고, 기다리지만 coroutineScope는 현재 스레드를 멈추게 하지 않습니다. 호출한 쪽이 suspend되고 시간이 되면 다시 활동하게 됩니다.

예제 12: Job을 이용한 제어

코루틴 빌더 launchJob객체를 반환하며 이를 통해 종료될 때까지 기다릴 수 있습니다.

import kotlinx.coroutines.* suspend fun doOneTwoThree() = coroutineScope { val job = launch { println("launch1: ${Thread.currentThread().name}") delay(1000L) println("3!") } job.join() launch { println("launch2: ${Thread.currentThread().name}") println("1!") } launch { println("launch3: ${Thread.currentThread().name}") delay(500L) println("2!") } println("4!") } fun main() = runBlocking { doOneTwoThree() println("runBlocking: ${Thread.currentThread().name}") println("5!") }

예제 13: 가벼운 코루틴

코루틴은 협력적으로 동작하기 때문에 여러 코루틴을 만드는 것이 큰 비용이 들지 않습니다. 10만개의 간단한 일을 하는 코루틴도 큰 부담은 아닙니다. (하지만 코틀린 플레이그라운드의 한계로 그렇게 많은 코루틴은 로그를 찍지 못합니다.)

import kotlinx.coroutines.* suspend fun doOneTwoThree() = coroutineScope { val job = launch { println("launch1: ${Thread.currentThread().name}") delay(1000L) println("3!") } job.join() launch { println("launch2: ${Thread.currentThread().name}") println("1!") } repeat(1000) { launch { println("launch3: ${Thread.currentThread().name}") delay(500L) println("2!") } } println("4!") } fun main() = runBlocking { doOneTwoThree() println("runBlocking: ${Thread.currentThread().name}") println("5!") }