728x90

 

코루틴(coroutine)

  • 최적화된 비동기 함수를 사용한다.
  • 하드웨어 자원의 효율적인 할당을 가능하게 한다.
  • 안정적인 동시성, 비동기 프로그래밍을 가능하게 한다.
  • 코루틴 쓰레드보다 더욱 가볍게 사용할 수 있다.(쓰레드를 경량화 한것 쓰레드의 대체가 아님) 
  • 구글에서 적극 권장한다. 

 

  • 쓰레드(Thread)
    • 로직을 동시에 실행할 수 있도록 함로직을 동시에 실행할 수 있도록 함 
    • 쓰레드프로세스보다 더 작은 단위 (프로세스 안에서 더 작은 작업의 단위를 쓰레드 라고 부름)
    • 쓰레드는 생성되서 수행할때 각 독립된 메모리 영역인 STACK 을 가지고, 스택메모리의 일정 영역을 차지한다.
    • 프로그램은 하나의 메인 쓰레드(실행흐름)가 존재하는데, 하나의 메인 쓰레드는  fun main() (메인 함수)를 의미함
  • 프로세스(Process)
    • 프로그램이 메모리에 올라가서 실행될때 이를 프로세스 1개 라고 한다.

메모리 자료

코루틴을 사용하려면 외부종속성을 추가한다. 

build.gradle.kts(Module :app) 의 dependencies

fun main() {
    thread(start = true) {
        for(i in 1..10) {
            println("Thread1: 현재 숫자는 ${i}")
            runBlocking {
                launch {
                    delay(1000) //1초 딜레이
                }
            }
        }
    }
    thread(start = true) {
        for(i in 100..110) {
            println("Thread2: 현재 숫자는 ${i}")
            runBlocking {
                launch {
                    delay(1000) //1초 딜레이
                }
            }
        }
    }
}

두 개의 쓰레드가 각각 1초를 지연하고 println() 을 실행하는데, 1초 후에 어느 쓰레드가 먼저 자원을 할당하는지에 따라 먼저 실행되는 쓰레드가 달라진다. (경주마 1번 2번 이라고 생각하면됨)

 

코루틴은 일반적으로 launchasync 빌더를 가장 많이 사용하고  launch는 결과값이 없는 코루틴 빌더를 의미한다. 

 

lanuch

launch는 결과값이 없는 코루틴 빌더를 의미한다.

Job객체로 코루틴을 관리한다. (Job객체는 다양한 함수를 가지고 있음 join,cancel)

  • join: 현재의 코루틴이 종료되기를 기다린다.
  • cancel: 현재의 코루틴을 즉시 종료한다. 

async

async는 결과값이 있는 코루틴이다. 

 

코루틴은 스코프로 범위를 지정할 수 있음

  • GlobalScope: 앱이 실행된 이후에 계속 수행되어야할때 사용한다.
  • CoroutineScope: 필요할때만 생성하고 사용후에 정리가 필요하다. 

 

코루틴을 실행할 쓰레드를 Dispatcher로 지정할 수 있음

 

withContext

Calls the specified suspending block with a given coroutine context, suspends until it completes, and returns the result. The resulting context for the block is derived by merging the current coroutineContext with the specified context using coroutineConte

kotlinlang.org

 

fun main() {
    println("메인쓰레드 시작")
    var job = CoroutineScope(Dispatchers.Default).launch {
        var fileDownloadCoroutine = async(Dispatchers.IO) {
            delay(10000)  
            "파일 다운로드 완료"
        }
        var databaseConnectCoroutine = async(Dispatchers.IO) {
            delay(5000)  
            "데이터베이스 연결 완료"
        }
        println("${fileDownloadCoroutine.await()}")
        println("${databaseConnectCoroutine.await()}")
    }
    runBlocking {
        job.join()
    }
    println("메인쓰레드 종료")
    job.cancel()
}

사용 후 정리가 필요한 CoroutineScope로 Dispatchers.Default로 지정해서 결과 값이 없는 launch로 열어주고 async로(Dispatchers.IO)가 10초 기다림 (10초 걸리는 파일 다운로드을 받아줌) 데이터베이스도 마찬가지 작업을 기다리고 작업이 끝나면 job.cancel()로 코루틴 종료 (runBlocking은 jvm 환경에서 코루틴을 사용해보기 위함 없으면 10초 되기전에 프로그램종료)

 

쓰레드 와 코루틴은 각자의 방법으로 동시성(비동기)을 보장하는 기술이고, 코루틴은 쓰레드를 대체하는 기술이아닌 쓰레드를 경량화한 기술임 

 

+ Recent posts