개발(Android)/kotlin syntax

[Android Studio/Kotlin syntax] Coroutine

shinyelee 2022. 4. 12. 15:06

[안드로이드 스튜디오/코틀린 문법] 코루틴

// Coroutine(코루틴) //

// 메인 루틴과 별도로 진행 가능한 루틴
// 개발자가 루틴의 실행과 종료를 마음대로 제어할 수 있는 단위
// 사용시 아래와 같이 임포트
import kotlinx.coroutines.*

fun main() {

    // 제어 범위와 실행 범위(스코프) 지정 가능 //
    
    // Global Scope(글로벌 스코프) -> 프로그램의 어디서나 제어 동작이 가능한 코루틴의 범위
    // Coroutine Scope(코루틴 스코프) -> 특정한 목적의 dispatcher(디스패처)를 지정해 제어 및 동작이 가능한 새로운 코루틴 범위 생성
    
    val scope = GlobalScope
    
    // 새로운 코루틴 생성 //
    
    // launch -> 반환값이 없는 Job 객체
    // async -> 반환값이 있는 Deffered 객체
    
    scope.launch {
        for(i in 1..5) {
            print(i)
        }
    }

    // 코루틴은 제어되는 스코프 또는 프로그램 전체가 종료되면 함께 종료됨
    // 코루틴이 끝까지 실행되는 것을 보장하려면
    // -> 일정한 범위에서 코루틴이 모두 실행될 때까지 기다려줘야 함

    // 현재 코드는 루틴이 main()함수 하나라서 프로세스가 거의 실행 즉시 종료됨
    // -> 코루틴 동작하지 않음

}

// Coroutine의 Dispatcher(코루틴 스코프를 만들 때 적용 가능한 디스패처) //

// Dispatchers.Default -> 기본적인 백그라운드 동작
// Dispatchers.IO -> IO에 최적화 된 동작
// Dispatchers.Main -> 메인(UI) 스레드에서 동작
// 일부 디스패처 지원 안되는 경우도 있으니 지원되는 플랫폼에 따라 사용해야 함
// 정상적인 실행

// 코루틴 동작하지 않음 -> runBlocking {}으로 코루틴이 종료될 때까지 메인 루틴을 잠시 대기시키면 됨

// 안드로이드에서는 메인 스레드에서 runBlocking을 걸어주면 일정 시간 응답이 없는 경우
// ANR(Application Not Responding, 응답 없음 오류)이 발생하며 앱이 강제 종료되니 유의할 것!

import kotlinx.coroutines.*

fun main() {
    
    runBlocking {
        launch {
            for(i in 1..5) {
            print(i)
            }
        }
    }
//    12345

}
import kotlinx.coroutines.*

// 루틴의 대기를 위한 추가적인 함수들 //

// delay(millisecond: Long) -> millisecond 단위로 루틴을 잠시 대기시키는 함수
// Job.join() -> Job의 실행이 끝날 때까지 대기하는 함수
// Deferred.await() -> Deffered의 실행이 끝날 때까지 대기하는 함수(Deffered의 결과도 반환)
// 코루틴 내부 또는 runBlocking{}과 같은 루틴의 대기가 가능한 구문 안에서만 동작 가능

fun main() {
    
    runBlocking {
        val a = launch {
            for(i in 1..5) {
            println(i)
            delay(10)
            }
        }
        
        val b = async {
            "async 종료"
        }
        
        println("async 대기")
        println(b.await())
        
        println("launch 대기")
        a.join()
        println("launch 종료")
        
    }
//    async 대기
//    1
//    async 종료
//    launch 대기
//    2
//    3
//    4
//    5
//    launch 종료

}
import kotlinx.coroutines.*

// cancel() //

// 코루틴에 캔슬을 걸어주면 다음 두 가지 조건이 발생하며 코루틴을 중단
// 1. 코루틴 내부의 delay() 함수 또는 yield() 함수가 사용된 위치까지 수행 후 종료
// 2. cancel()로 인해 속성인 isActive가 false가 됨 -> 수동 종료

fun main() {
    
    runBlocking {
        val a = launch {
            for(i in 1..5) {
            println(i)
            delay(10)
            }
        }
        
        val b = async {
            "async 종료"
        }
        
        println("async 대기")
        println(b.await())
        
        println("launch 취소")
        a.cancel()
        println("launch 종료")
        
    }
//    async 대기
//    1
//    async 종료
//    launch 취소
//    launch 종료

}
import kotlinx.coroutines.*

fun main() {
    
    runBlocking {
        var result = withTimeoutOrNull(50) {
            for(i in 1..10) {
                println(i)
                delay(10)
            }
            "Finish"
        }
        println(result)
    }
//    1
//    2
//    3
//    4
//    null

}

// timeout 내에 수행할 수 없음 -> 가능한 데까지 하다가 null 출력하고 끝

참고

 

[kotlin] 코루틴 공부하기 (비동기 처리, 서버 딜레이 처리)

빌어먹을 코루틴... 저번에 공부하다가 도저히 못해먹겠어서 포기했다가 오늘 다시 도전했다. 항상 느끼는 거지만 아무것도 모를 땐 그렇게 어렵게 느껴지다가 또 막상 성공하면 아 이걸 왜 이

todaycode.tistory.com

 

콜백 함수(Callback function)란 무엇일까?

오늘은 콜백 함수에 대해 공부하기로 했다. 사실 이번에 토이 프로젝트를 하기 전까지는 콜백 함수가 뭔지 몰랐다. 아니 존재 자체도 몰랐다. 보고 따라 사용하면서도 내가 잘 이해하면서 쓰고

todaycode.tistory.com

반응형