일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ㅓ
- r
- F
- El
- 빌터패턴
- 추상팩토리패턴
- builderPattern
- Design Pattern
- factory method
- Abstract Factory
- Singleton
- 옵저버 패턴
- 추상 팩토리
- ㅋㅁ
- 함수형프로그래밍
- Observer Pattern
- 디자인패턴
- Kotlin
- a
- 팩토리 메소드
- 코틀린
- 디자인패턴 #
- PrototypePattern
- designPattern
- 싱글톤
- 프로토타입 패턴
- Functional Programming
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
coroutine basics(코루틴의 기초 공식문서 번역 설명) 본문
* 배경지식
process (프로세스)
- 실행중인 응용프로그램() 인스턴스이다, 어플리케이션은 여러개의 프로세스로 구성될 수 있다.
- 운영체제로부터 자원(메모리, CPU, 네트워크 등)을 할당받은 작업의 단위
thread(쓰레드)
- 프로세스가 할당받은 자원을 이용하는 실행 흐름의 단위.
- 스레드(thread)란 프로세스(process) 내에서 실제로 작업을 수행하는 주체
- 모든 프로세스에는 한 개 이상의 스레드가 존재하여 작업을 수행
coroutine(코루틴)
- 일시적으로 중단 가능한 코드 블록.
- 동시에 작동하는 코드 블록을 실행하다는점은 Thread와 유사하다
- coroutine은 특정 스레드에서 실행되는 것이 아니라, 특정 쓰레드에서 실행되다 중단되고 다시 이전 쓰레드와 다른 쓰레드에서 실행 가능
- 코루틴은 경량 스레드로 생각할 수 있지만, 실제 사용에 있어서 차이점이 많다
첫번째 코루틴
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello") // main coroutine continues while a previous one is delayed
}
launch
- 코루틴 Builder 중 하나이다.
- 독립적으로 계속 작동하는 나머지 코드와 동시에 새 코루틴을 시작.
delay
- 특별한 suspend function.
- 특정 시간 동안 코루틴을 일시 중단.
- 코루틴을 일시 중단하면 기본 스레드가 차단되지 않지만 다른 코루틴이 실행되고 코드에 기본 스레드를 사용할 수 있습니다.
runBlocking { ... }
- 블록안에 새 코루틴을 실행하고 완료될때 까지 현재 쓰레드를 차단한다.
- 다른 코루틴 블록내에서 사용하면 안된다.
- suspending style로 작성된 라이브러리의 주요 기능 및 테스트에 사용 하기 위해 만듬.
- 일반 fun main()의 비코루틴 세계와 runBlocking { ... } 중괄호 내부의 코루틴이 있는 코드를 연결하는 코루틴 Builder
Structured concurrency ( 구조화된 동시성)
코루틴은 구조화된 동시성의 원칙을 따른다.
즉, 새로운 코루틴은 코루틴의 수명을 제한하는 특정 CoroutineScope에서만 시작될 수 있다
- coroutines은 손실되지 않고 누출되지 않도록 합니다.
- 외부 범위는 모든 하위 코루틴이 완료될 때까지 완료할 수 없습니다
1. {
2. launch { ... }
3. launch { ....
4. launch { ... }
}
}
4번이 끝나야 3번이 끝나고, 2, 3끝나야 1번 블록이 종료된다.
- 코드의 모든 error 가 적절하게 전달 되고 손실 않음.
Extract function refactoring( 함수 추출을 통한 리펙토링)
fun main() = runBlocking { // this: CoroutineScope
launch { doWorld() }
println("Hello")
}
// this is your first suspending function
suspend fun doWorld() {
delay(1000L)
println("World!")
}
suspend 붙혀서 새 함수를 생성한다.
suspend 함수는 일반 함수와 마찬가지로 코루틴 내부에서 사용할 수 있지만, 차이점은 순차로 다른 suspend 함수(delay)을 사용하여 코루틴 실행을 일시 중단할 수 있다.
Scope builder
기본 제공하는 코루틴 scope 외에도 coroutineScope 빌더를 사용하여 고유한 범위를 선언할 수 있다.
coroutineScope를 만들고 실행된 모든 자식이 완료될 때까지 완료되지 않습니다.
runBlocking 및 coroutineScope 빌더는 모두 본 블록과 모든 하위 코루틴이 완료될 때까지 기다리기 때문에 비슷해 보일 수 있다.
차이점은 runBlocking 메서드는 대기를 위해 현재 스레드를 차단하는 반면 coroutineScope는 suspend(중단)하여 다른 일을 위해 스레드를 이용한다.
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
}
public suspend fun <R> coroutineScope(block: suspend CoroutineScope.() -> R): R {
}
Scope builder and concurrency
coroutineScope 빌더는 suspend function 안에서 여러 동시 작업을 수행하는 데 사용할 수 있습니다.
// Sequentially executes doWorld followed by "Done"
fun main() = runBlocking {
doWorld()
println("Done")
}
// Concurrently executes both sections
suspend fun doWorld() = coroutineScope { // this: CoroutineScope
launch {
delay(2000L)
println("World 2")
}
launch {
delay(1000L)
println("World 1")
}
println("Hello")
}
launch { ... } 블록 내부의 두 코드는 동시에 실행
An explicit job (명시 작업)
launch 코루틴 빌더는 시작된 코루틴에 대한 job 개체를 반환하고 명시적으로 완료를 기다리는 데 사용할 수 있다.
예를 들어, 자식 코루틴이 완료될 때까지 기다린 다음 "Done" 문자열을 인쇄할 수 있습니다.
val job = launch { // launch a new coroutine and keep a reference to its Job
delay(1000L)
println("World!")
}
println("Hello")
job.join() // wait until child coroutine completes
println("Done")
Coroutines are light-weight
코루틴은 JVM Thread 보다 리소스 집약적입니다.
스레드를 사용할 때 JVM의 가용 메모리를 소모하는 코드는 리소스 제한에 도달하지 않고 코루틴을 사용하여 표현할 수 있습니다.
예를 들어, 다음 코드는 각각 5초를 기다린 다음 매우 적은 메모리를 소비하면서 마침표('.')를 인쇄하는 100000개의 고유한 코루틴을 시작합니다.
import kotlinx.coroutines.*
fun main() = runBlocking {
repeat(100_000) { // launch a lot of coroutines
launch {
delay(5000L)
print(".")
}
}
}
스레드를 사용하여 동일한 프로그램을 작성하는 경우(runBlocking 제거, 시작을 스레드로 교체, 지연을 Thread.sleep으로 교체) 메모리를 너무 많이 소비하고 메모리 부족 오류가 발생할 수 있습니다.
'Coroutine > coroutineBasic' 카테고리의 다른 글
Coroutine scope (0) | 2022.07.07 |
---|---|
Coroutine context and dispatchers (0) | 2022.07.06 |
Composing suspending functions (suspend 함수 구성하기) (0) | 2022.07.05 |
Cancellation and timeouts (0) | 2022.07.05 |