CoroutineScope
CoroutineScope는 CoroutineContext 하나만 맴버 속성으로 정의하고 있는 인터페이스 입니다.
(CoroutineContext 는 Coroutine을 어떻게 처리 할지에 대한 정보를 가지고있는 객체입니다.)
코루틴의 구조적인 동시성을 위해 모든 코루틴은 CoroutineScope에서만 실행할 수 있도록 제어합니다.
모든 CoroutineBuilder는 CoroutineScope의 확장 함수로 정의된다.
이들이 Coroutine을 생성할 때는 소속된 CoroutineScope에 정의 된 CoroutineContext를 가지고
코루틴을 생성한다.
CoroutineScope는 각각의 라이프 사이클을 별도로 가지고 종료를 할 수 있다.
간단사용 예제
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.2")
}
사용하기전에 Coroutine 라이브러리 추가해주자!
suspend fun main() {
val deferred : Deferred<String> = CoroutineScope(Dispatchers.IO).async {
coroutine()
}
print("Hello ")
println(deferred.await())
}
suspend fun coroutine() : String {
delay(3000)
return "Coroutine!"
}
간단하게 설명하겠습니다.
CoroutineScope는 CoroutineContext 하나만 맴버 속성으로 정의하고 있는 인터페이스라고 했습니다.
CoroutineScope(Dispatchers.IO) << 그래서 이부분을 보면 CoroutineScope안에 Dispatchers.IO를 넣었죠.
Dispatchers 는 CoroutineContext중 하나로써 Coroutine을 어떤 스레드에서 실행시킬것인지 정합니다.
Dispatchers.IO는 간단한게 IO작업에 쓰는 쓰레드를 사용한다는 뜻입니다. 자세한건 나중에 Dispatchers편에서 하겠습니다.
.async는 비동기로 처리하겠다는 뜻 입니다. async는 반환값을 deferred를 안에 넣어서 반환합니다.
그래서 변수 deferred 의 자료형은 deferred<String> 입니다. 즉 문자열을 반환받겠다는 겁니다.
즉 async를 하면 비동기로 작업을 처리한뒤 결과값을 deferred<T> 형태로 변수에 담을 수 있습니다.
저기에서는 작업을 coroutine()함수를 했습니다.
suspend fun coroutine() : String {
delay(3000)
return "Coroutine!"
}
coroutine() 함수를 살펴보면 fun앞에 suspend가 붙어있습니다. 이것은 delay이라는 중단함수가 코루틴안에서만 동작합니다. 그래서 일반 fun으로만 함수를 만들면 delay을 사용할 수 없습니다. 이럴때 앞에 suspend 키워드를 붙여서 사용할 수 있습니다.
delay(3000) 3초동안 현재 쓰레드를 Blocking 시킵니다. 3초뒤에 "Coroutine!" 문자열을 반환해줍니다.
async의 마지막 부분은 리턴값으로 이용됩니다. 즉 함수를 호출해서 받아온 문자열을 리턴합니다.
그리고 print로 Hello를 찍고 그 다음으로 println 으로 deferred.awit() 하는데요
deferred.awit() 은 위에 async로 만든 코루틴에서 값이 반환될 때 까지 기다리겠다는 것입니다.
Deferred 메소드 입니다.
실행
코드처럼 Hello 찍히고 Coroutine!이 찍혔습니다.
여기서 비동기를 설명해드리겠습니다.
println(deferred.await()) 이 부분이 실행될때부터 위에 만든 deferred가 실행된다고 생각하시는 분이 있을거라 생각합니다.
Hello로 가 찍히고 그뒤로 deferred가 실행되니깐 그때부터 delay3초 기달리고 3초뒤에 "Coroutine!"
이 출력되는것처럼 보입니다.
suspend fun main() {
val deferred : Deferred<String> = CoroutineScope(Dispatchers.IO).async {
coroutine()
}
print("Hello ")
delay(3000)
println(deferred.await())
}
suspend fun coroutine() : String {
delay(3000)
return "Coroutine!"
}
그렇다면 이코드는 "Hello" 가 찍히고 delay로 3초를 지연시키고 그뒤로 deferred.await()을 했으니 6초뒤에
"Coroutine!" 이 찍힐까요? 아닙니다. 우리는 .async 비동기처리로 coroutine() 함수를 실행시켰습니다.
그럼이미 맨처음 코드를 읽을때부터 다른 코루틴에서 coroutine() 함수를 실행시키고 있는것입니다.
main()안에 있는 delay로 3초를 지연시켜도 다른코루틴에서는 지연없이 결과값을 만들고 있는 상황입니다.
그래서 3초뒤면 이미 결과값이 deferred에 넘어와있는 상태입니다. 그래서 deferred.awit()을 하면 바로 결과값이 출력됩니다.
그림으로 설명하자면 이런느낌?? 이다..
첫번째 그림예시에 delay(3000) 말고 다른 작업을 넣으면 그 작업을 하면서 작업이 다끝난다음에는
(비동기로 작업했던)3초가걸리는 작업의 결과를 바로 받아올수있는것이다.. 이것이 비동기??
글 봐주셔서 감사합니다. 이해안가는부분이나 틀린부분있으면 댓글로 알려주세요.
'Android-Kotlin > Coroutine' 카테고리의 다른 글
[Coroutine] Job 이란 ? - Kotlin (0) | 2022.06.26 |
---|---|
[Coroutine] launch란? 간단 사용법 - Kotlin (0) | 2022.06.25 |
[Coroutine] Dispatcher 란? - Kotlin (0) | 2022.06.22 |