Android

코루틴

김한토 2024. 5. 24. 20:09
반응형

 

스레드 (Thread)

 스레드는 프로그램 범위 내에서 예약하고 실행할 수 있는 코드의 최소 단위.. 멀티스레딩을 지원함으로써 사용자에게 원활한 실행을 제공한다. 하지만 한정된 시간안에 UI를 준비하고 그려야하는데 이것이 복잡해지면 앱이 멈춰버린다. 또한 여러 스레드가 동시에 메모리의 동일한 값에 액세스하려고 할 때 경합 상태가 발생할 수 있다. 그래서 스레드를 직접 사용하는 것을 권장하지 않는다.

 

코틀린 코루틴(Kotlin Coroutine)

 

 백그라운드 작업을 위한 스레드를 만들고 사용하는 것은 android에서 이루어지지만 코틀린은 동시 실행을 더 유연하고 쉽게 관리할 수 있는 코루틴도 제공한다. 

 

코루틴 기능

1. 상태를 저장하여 중단했다가 재개할 수 있음

2. 코루틴은 실행되거나 실행되지 않을 수 있음.

3. 코드 일부가 제어권을 넘겨주거나 재개되기 전에 다른 코루틴 작업을 기다리는 시기를 나타낼 수도 있음. => 협력적 멀티태스킹

 

CoroutineScope : 하위 요소와 그 하위 요소에 취소 및 기타 규칙을 반복적으로 적용하는 컨텍스트

- MainScope : 메인 UI 스레드에서 사용할 수 있다.

- GlobalScope : 앱 전체 생명 주기를 갖는다.

Job : 코루틴스콥 내에서 수명주기가 있는 취소 가능한 작업 단위, 코루틴이 어떤 상태인지 확인할 수 있따.

Dispatcher : 코루틴이 실행에 사용할 지원스레드 관리 => 개발자가 새 스레드를 사용할 시기와 위치를 파악하지 않아도됨

==>> 스레드풀을 왔다갔다하며 관리하며 작업을 할 수 이따, 컨텍스트 스위칭 비용이 낮아짐..

 

launch

//예제 코드

private fun launchExample(){
	lifecycleScope.launch {
    	delay(3000)
        Lod.d("KC", "1. ${Thread.currentThread().name})
    }
    Lod.d("KC", "1. ${Thread.currentThread().name})
}

 


//실행결과 
2.main이 먼저 나오고 
1.main이 3초뒤 실행된다.

 

=>> 보통 1번이 3초뒤에 실행되고 2번이 출력될 것을 예상되는데 2번이 먼저 출력됐다는 것은 launchExample이 실행된 메인스레드는 다음작업을 수행해야하는 2번의 연산을 차단하지 않고 이거 먼저 수행하고 3초 뒤에 본인이 연산을 해야하는 작업을 마저 수행한 것으로 볼 수가 있다.

 

=>> 코루틴 스콥으로 우리가 수행하는 연산은 메인 스레드를 차단하지 않고 작업을 수행한다. 그렇기 때문에 네트워크 통신을 할 대, 코틀린 코루틴을 사용하는 것이 간편하다.

 

join

//예제 코드

private fun joinExample(){
	val job = lifecycleScope.launch {
    	delay(3000)
        Lod.d("KC", "1. ${Thread.currentThread().name}")
    }
    job.join
    Lod.d("KC", "1. ${Thread.currentThread().name}")
}

 

join은 결과 순서가 꼭 1번 다음에 2번이 나온다.

=>> join함수는 앞서서 실행한 job이 다 종료될 때까지 기다리고 있따. 

 

suspend

- 잠시 이후의 연산을 일시 중지 시킨다. 

- 서스펜드는 이후의 연산을 블로킹하는 것이 아니라 결과가 도착하기 전까지 잠시 이후의 연산이 일시 중단됐다가 결과가 도착이 되면 이후의 연산이 재개되는 형태이다.

 

async

 

//예제 코드

private fun asyncExample(){
	lifecycleScope.launch {
    	val deferredJob = lifecycleScope.async {
        delay(3000)
        Lod.d("KC", "1. ${Thread.currentThread().name})
        listOf(1,2,3)
        }
    }
    Lod.d("KC", "2. ${Thread.currentThread().name})
    val result = deferredJob.await()
    Lod.d("KC", "3. ${Thread.currentThread().name}, result: ${result}")
}

 

//실행결과 

2. main

3초 뒤 1. main

3.main, result : {1,2,3}

 

=>> async 함수도 이후에 선언된 코드를 블록킹하지 않는다. 

어떤 값을 반환하는데 그 반환하는 값은 람다의 마지막 줄에서 연산된 결과(list)가  반환된다

 

네트워크 같은 복잡한 쓰레드는 -> worker

UI를 띄우는 쓰레드는 -> main

네트워크 통신을 요청하는 스레드 유형은 백그라운드, 결과값이 도착했을때는 메인스레드가 되어야 한다.

코루틴은 아니지만 runOnUi, post를 사용해서 작업을 할 수 있음

코루틴은? WithContext를 사용하면 디스패처의 유형을 중간에 변경해서 연산을 요청할 수 있게 된다. 

 

 

 

출처 : 

https://developer.android.com/codelabs/basic-android-kotlin-training-introduction-coroutines?hl=ko#3

 

코루틴 소개  |  Android Developers

코루틴 소개

developer.android.com

 

으아.. 어렵드아아아

반응형

'Android' 카테고리의 다른 글

[삽질] Recycler View 값이 없을 때 안보이게 하기  (0) 2024.06.08
Room  (1) 2024.06.04
동기 / 비동기  (0) 2024.05.20
Json / 직렬화 / 역직렬화  (0) 2024.05.16
Android 리사이클러뷰  (0) 2024.05.06