# 시작하며
앱공부를 하다보니까, 아키텍처와 코루틴의 중요성을 알게 됐다. 그래서 책도사고 여러가지 공부할 방법을 고심했는데, 결국 강의하나를 질렀다. 코루틴에 대해서 셜명해주는 강의인데, 공부한 내용을 바탕으로 정리하도록 하겠다.
이번에는 첫강의인 만큼 코루틴이 어떤 것이며 어떻게 사용하는지에 대한 감을 익히는 방법이 주된 내용이었다. 강의에 나온 예제를 바탕으로 중요한 개념들을 정리해볼까 한다.
# runBlocking
import kotlinx.coroutines.*
fun main() = runBlocking {
println(Thread.currentThread().name)
println("Hello")
}
runBlocking는 코루틴을 생성하는 함수 중 하나이다. 이것을 코루틴 빌더라고 한다. runBlocking의 스코프의 실행이 다 끝나야만 다른 코드가 실행 될 수 있다.
import kotlinx.coroutines.*
fun main() = runBlocking {
println(this)
println(Thread.currentThread().name)
println("Hello")
}
runBlocking의 수신객체로는 코루틴이 들어온다. this를 받아와 실행해보면 코루틴이 수신 객체인 것을 알 수 있으며, 그렇기 때문에 코루틴 스코프 안에서는 코루틴 객체를 사용할 수 있는 것이다.
import kotlinx.coroutines.*
fun main() = runBlocking {
println(coroutineContext) // 같음
println(this.coroutineContext) // 같음
println(Thread.currentThread().name)
println("Hello")
}
코루틴 스코프에는 코루틴을 처리하기 위한 정보를 가지고 있는데 이것이 코루틴 컨택스트이다.
# launch
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
println("launch: ${Thread.currentThread().name}")
println("World!")
}
launch {
println("launch: ${Thread.currentThread().name}")
println("111!")
}
launch {
println("launch: ${Thread.currentThread().name}")
println("222!")
}
println("runBlocking: ${Thread.currentThread().name}")
println("Hello")
}
// 실행 결과
runBlocking: main @coroutine#1
Hello
launch: main @coroutine#2
World!
launch: main @coroutine#3
111!
launch: main @coroutine#4
222!
runBlocking와 같이 launch를 이용해서도 코루틴을 생성할 수 있다. 이 또한 코루틴 빌더라고 부를 수 있을 것 같다. launch는 코루틴 스코프 내에서 사용이 가능하다. 위 코드에서는 runBlocking내의 코드가 main쓰레드를 먼저 가지고 있기 때문에 런치로 생성한 코루틴은 큐에 들어가서 기다리게 된다. runBlockin은 안에 있는 다른 코드들의 실행이 모두 끝나야만 종료 된다.
# delay함수
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
println("launch: ${Thread.currentThread().name}")
println("World!")
}
println("runBlocking: ${Thread.currentThread().name}")
delay(100L)
println("Hello")
}
runBlocking: main @coroutine#1
launch: main @coroutine#2
World!
Hello
delay함수는 현재 점유하고있는 쓰레드를 양보한다. 즉 다른 코루틴이 그 쓰레드를 사용 할 수 있다는 뜻이 된다. 위 코드는 runBlocking스코프에서 delay(100L)을만나 쓰레드를 양보한다. 그럼 큐에 있던 launch{..}내의 코드가 실행 되고 다시 Hello가 실행된다. 이러한 delay를 suspension point(중단점)이라고 한다. 이게 Thread.sleep()와 다른 점이다. 즉 위 코드에서는 0.1초의 시간이 delay되지만 그 시간동안에는 launch{..}안의 코드가 실행 된다는 점이다.
# Sleep
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
println("launch: ${Thread.currentThread().name}")
println("World!")
}
println("runBlocking: ${Thread.currentThread().name}")
Thread.sleep(500)
println("Hello")
}
runBlocking: main @coroutine#1
Hello
launch: main @coroutine#2
World!
0.5초 기다린 후 Hello가 실행되고 launch안에 코드가 실행된다.
# suspend
import kotlinx.coroutines.*
suspend fun doThree() {
println("launch1: ${Thread.currentThread().name}")
delay(1000L)
println("3!")
}
suspend fun doOne() {
println("launch1: ${Thread.currentThread().name}")
println("1!")
}
suspend fun doTwo() {
println("runBlocking: ${Thread.currentThread().name}")
delay(500L)
println("2!")
}
fun main() = runBlocking<Unit> {
launch {
doThree()
}
launch {
doOne()
}
doTwo()
}
delay, launch와 같은 함수들은 코루틴 내에서 호출 할 수 있었다. 이 것들을 함수로 분리시키기 위해서는 suspend라는 키워드를 사용해야 한다. 'suspend'를 번역하면 '유예한다'라는 뜻을 가짐을 알 수 있다. 코루틴 스코프내에서 쓰이는 함수는 주로 suspend 키워드를 붙여서 선언해준다. doOne()함수는 delay() 함수를 사용하지 않았기 때문에 suspend키워드를 붙이지 않아도 오류가 나지는 않는다.
# 마치며
패스트캠퍼스 김용욱님의 코루틴 강의를 참고하여 글을 작성했습니다.
'•App > 코틀린(Kotiln)' 카테고리의 다른 글
[코루틴#2] 코루틴 스코프(Coroutine Scope)와 잡(Job)을 이용한 join (0) | 2022.08.05 |
---|---|
[코틀린 문법] 코틀린에서 for문과 when문 사용방법, 코틀린 반복문 (0) | 2022.03.12 |
[코틀린 문법] 코틀린에서 ? 와 !! 사용법 및 nullable에 대해서, nullsafe (0) | 2022.03.12 |