티스토리 뷰
링크는 구글 코드랩
스레드
앱에서 코드를 실행하는 단일 경로 -> 개발자가 작성하는 각 코드 줄은 동일한 스레드에서 순서대로 실행될 명령어
안드로이드 앱에는 기본스레드가 있음 -> 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의 개념
코루틴은 협력작업, 예외, 이벤트 루프, 반복자, 무한 목록 및 파이프와 같은 구성요소 구현에 적합하다.
비동기 처리를 쉽게 해준다..
'#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 |