ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Kotlin Coroutines(2)
    Kotlin 2021. 5. 26. 14:35

    코루틴 제어

    코루틴을 시작하는 방법은 두 가지가 있으며 용도가 다릅니다

     

    launch() 함수로 시작된 코루틴 블록은 Job 객체를 반환, 결과값을 반환하지 않는다.

    async() 함수로 시작된 코루틴 블록은 Deferred<T>를 반환, await라는 일시 중지 함수로 결과를 반환한다

    launch() - Job

    반환받은 Job 객체로 코루틴 블록을 취소하거나, 다음 작업의 수행전 코루틴 블록이 완료 되기를 기다릴수 있다.

    fun main() = runBlocking {
        val job = launch { // launch a new coroutine and keep a reference to its Job
            delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
            println("World!")
        }
        println("Hello")
        job.join() // wait until child coroutine completes
        println("Done") 
    }

    결과

     Hello
     World!
     Done

    여러개의 launch 코루틴 블록을 실행할 경우 각각의 Job 객체에 대해서 join() 함수로 코루틴 블록이 완료 될때까지 다음 코드 수행을 대기할수 있다.

    fun main() = runBlocking {
       val job1 : Job = launch {		
            delay(2000L)
            println("JOB_1")
        }
    
        val job2 = launch {		
            delay(1000L)
            println("JOB_2")
        }
    
        job1.join() // wait until child coroutine completes
        job2.join()
        println("Done")           
    }

    결과

     JOB_2
     JOB_1
     Done

    모든 Job 객체에 대해서 일일히 join() 함수를 호출하지 않고 joinAll() 함수를 이용하여 모든 launch 코루틴 블록이 완료 되기를 기다릴수도 있다.

    joinAll(job1, job2)

    CoroutineScope Builder로 여러 작업을 동시에 수행하기

    // doWorld 다음에 "Done"을 차례로 실행
    fun main() = runBlocking {
        doWorld()
        println("Done")
    }
    
    // 두 sections을 동시에 실행
    suspend fun doWorld() = coroutineScope { // this: CoroutineScope
        launch {
            delay(2000L)
            println("World 2")
        }
        launch {
            delay(1000L)
            println("World 1")
        }
        println("Hello")
    }

    결과

     Hello
     World 1
     World 2
     Done

    async() - Deferred

    async() 함수로 시작된 코루틴 블록은 Deferred 객체를 반환한다.

    fun main() = runBlocking {
        val deferred : Deferred<String> = async {
    	delay(2000L)
            "result"
        }
        val msg = deferred.await()
        println(msg) //print result
    }

    여러 개의 async 코루틴 블록에 같은 Deferred 객체를 사용하는 경우 await() 함수 호출시 전달되는 최종적인 결과값은 첫번째 async 코루틴 블록의 결과값 만을 전달한다.

    fun main() = runBlocking {
        val deferred : Deferred<String> = async { 		
            delay(2000L)
            "result1"
        }
        
        async(deferred){
            delay(1000L)
            "result2"
        }
        
        val msg = deferred.await()
        println(msg) //첫번째 블록 결과인 result1 출력
    }

    runBlocking()

    runBlocking() 함수로 시작된 블록은 작업이 완료하기까지 스레드를 점유, 대기한다.

    주의해야 할 점은 runBlocking() 코루틴 블록이 사용하는 스레드는 runBlocking() 함수가 호출된 스레드가 된다는 점이다. 안드로이드의 경우 메인 스레드(UI 스레드)에서 호출하여 오래 걸리는 작업을 실행할 경우 ANR이 발생할 위험이 있다.

     

    References

     

    'Kotlin' 카테고리의 다른 글

    Kotlin Coroutines(3)  (0) 2021.05.27
    Kotlin Coroutines(1)  (0) 2021.05.22
Designed by Tistory.