티스토리 뷰

#1/Android

[Android/Kotlin] 코루틴

_쿠나 2021. 5. 24. 12:20

링크는 구글 코드랩

 

스레드

앱에서 코드를 실행하는 단일 경로 -> 개발자가 작성하는 각 코드 줄은 동일한 스레드에서 순서대로 실행될 명령어

 

안드로이드 앱에는 기본스레드가 있음 -> UI 스레드(기본 스레드)

기본 스레드 외의 스레드에서 백그라운드 작업: 동시 실행 코드/ 동시 실행 (Concurrency)

 

동시실행

여러 코드 단위를 뒤죽박죽, 또는 병렬 실행 가능 -> 리소스 사용 효율성이 높아진다.

 

단일 실행 경로

동시실행(Concurrency)

 

동시 실행을 올바르게 구현하지 않으면 앱이 사용자에게 응답하지 않는 것으로 보일 수 있다.

 

스레드를 코드에서 직접 사용하면 여러 문제가 발생할 수 있다.

1. 많은 리소스가 필요한 스레드

  - 작업 완료까지 스레드를 차단해 앱이 응답하지 않는 원인이 된다. 

2. Race condictions 와 예측할 수 없는 동작

  - race condition; 여러 스레드가 동시에 메모리의 동일한 값에 접근하려 할 때 발생한다.

 

이런 문제에 대해서...

코루틴은 동시 실행 코드 작성에 도움이 되는 Kotlin의 기능이다.

 

안드로이드: 백그라운드 작업을 위한 스레드를 직접 만들고 사용한다.

코틀린 코루틴: 동시 실행을 더 유연하고 쉽게 관리한다.

 

코루틴으로 멀티태스킹을 할 수 있다.. 

코루틴의 주요 기능: 상태를 저장하여 중단했다가 재개할 수 있다 >> pause resume 가능!!

 

코루틴을 만드는 것

continous, job, coroutineScope, Dispatcher

job: 취소 가능한 작업 단위(launch() 함수로 만든 작업단위)

CoroutineScope: launch() 및 async()같은 새 코루틴을 만드는 데 사용되는 함수는 CoroutineScope를 확장한다

Dispatcher: 코루틴이 사용할 스레드를 결정함

 

runBlocking(): 새 코루틴을 시작하고 완료될 때 까지 현재 스레드를 차단

일반적인 안드로이드 코드에서는 자주 사용하지 않음, 기본 함수와 테스트에서 차단 코드와 비차단 코드를 연결하는데 사용

 

 

import kotlinx.coroutines.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

val formatter = DateTimeFormatter.ISO_LOCAL_TIME
val time = { formatter.format(LocalDateTime.now()) }

suspend fun getValue(): Double {
    println("entering getValue() at ${time()}")
    delay(3000)
    println("leaving getValue() at ${time()}")
    return Math.random()
}

fun main() {
    runBlocking {
        val num1 = getValue()
        val num2 = getValue()
        println("result of num1 + num2 is ${num1 + num2}")
    }
}

얘를 실행시키면

entering getValue() at 02:22:08.256
leaving getValue() at 02:22:11.266
entering getValue() at 02:22:11.268
leaving getValue() at 02:22:14.268
result of num1 + num2 is 0.9741153554708739

 

이렇게 바꾸면

import kotlinx.coroutines.*
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter

val formatter = DateTimeFormatter.ISO_LOCAL_TIME
val time = { formatter.format(LocalDateTime.now()) }

suspend fun getValue(): Double {
    println("entering getValue() at ${time()}")
    delay(3000)
    println("leaving getValue() at ${time()}")
    return Math.random()
}

fun main() {
    runBlocking {
        val num1 = async { getValue() }
        val num2 = async { getValue() }
        println("result of num1 + num2 is ${num1.await() + num2.await()}")
    }
}

getValue()호출이 독립적이기 때문에 정지하는 데 코루틴이 필요하지 않다.. 

async() 함수는 Deffered 유형의 값을 반환한다... 

Deffered: 미래의 값 참조를 보유할 수 있는 취소 가능한 Job이다.. 미리 자리 잡아둠을 의미한다는 듯.

 

entering getValue() at 02:20:34.7
entering getValue() at 02:20:34.704
leaving getValue() at 02:20:37.704
leaving getValue() at 02:20:37.706
result of num1 + num2 is 1.2819769457546493

suspend: 함수 블록이 일시중지 되거나 재개될 수 있음을 나타냄

코루틴 코드에선 suspend 한정자를 함수에 추가했습니다. 이것은 컴파일러에게 이 함수가 코루틴 안에서 실행되어야 한다는 것을 알려주게 됩니다. 개발자로서 suspend 기능은 어느 시점에 실행이 중단되고 재개될 수 있는 정기적인 기능이라고 생각할 수 있습니다.

 

 

getValue() 함수는 suspend 함수에 속하는 delay()를 호출하므로 suspend 키워드로 정의될 수 있다.

main()은 직접 getValue()를 호출하지 않고 ... 그래서 suspend 키워드로 정의 못한다

 

 

 

+ by youtube

루틴의 일종, pause와 resume이 됩니다.

(이전에 자신의 실행이 마지막으로 중단되었던 지점 다음부터 실행을 재개한다)

일반 루틴은 stop, start의 개념

코루틴은 협력작업, 예외, 이벤트 루프, 반복자, 무한 목록 및 파이프와 같은 구성요소 구현에 적합하다. 

비동기 처리를 쉽게 해준다..

 

 

 

 

728x90

'#1 > Android' 카테고리의 다른 글

[Android] application Id - 어플을 복사하자!  (0) 2021.05.31
[Android/java] Room 사용하기  (0) 2021.05.31
뷰바인딩  (0) 2021.05.21
[Android] requireActivity  (0) 2021.05.14
비트맵  (0) 2021.05.14
댓글
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함