일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 플러터 설치 2022
- rxjava disposable
- 안드로이드 라이선스 종류
- 안드로이드 레트로핏 사용법
- 안드로이드 유닛테스트란
- rxjava hot observable
- ANR이란
- 안드로이드 레트로핏 crud
- android ar 개발
- jvm이란
- 객체
- 멤버변수
- 스택 자바 코드
- rxjava cold observable
- 2022 플러터 안드로이드 스튜디오
- Rxjava Observable
- 스택 큐 차이
- 2022 플러터 설치
- jvm 작동 원리
- 안드로이드 유닛 테스트 예시
- 자바 다형성
- 서비스 vs 쓰레드
- android retrofit login
- 안드로이드 라이선스
- 안드로이드 os 구조
- 안드로이드 유닛 테스트
- 서비스 쓰레드 차이
- 큐 자바 코드
- 클래스
- ar vr 차이
- Today
- Total
목록책/코틀린 코루틴 (20)
나만을 위한 블로그
코루틴의 중요 기능은 코루틴이 실행돼야(시작, 재개 등) 할 쓰레드(또는 쓰레드 풀)를 결정할 수 있는 것이다. 디스패처로 이 기능을 쓸 수 있다. 코루틴이 어떤 쓰레드에서 실행될지 정하는 건 CoroutineContext다. 기본 디스패처 디스패처를 설정하지 않으면 기본 설정되는 디스패처는 CPU 집약적 연산을 수행하게 설계된 Dispatchers.Default다. 이 디스패처는 코드가 실행되는 컴퓨터의 CPU 개수와 같은 수(최소 2개 이상)의 쓰레드 풀을 갖고 있다. 쓰레드를 효율적으로 쓴다고 가정하면 이론적으로 최적의 쓰레드 개수라고 할 수 있다. 기본 디스패처 제한하기 고비용 작업이 Dispatchers.Default의 쓰레드를 다 써서 같은 디스패처를 쓰는 다른 코루틴이 실행될 기회를 제한하고..
여러 엔드포인트에서 데이터를 동시에 얻어야 하는 중단 함수를 구현할 때 차선책은 뭐가 있을까? 코루틴 스코프 함수 전에 쓰인 방법들 첫 번째 방법은 중단 함수에서 중단 함수를 호출하는 것이다. 문제는 작업이 동시에 진행되지 않는다는 것이다. 하나의 엔드포인트에서 데이터를 얻는데 1초 걸려서 함수가 끝나려면 2초가 걸린다. 두 중단 함수를 동시 실행하려면 각각 async로 래핑해야 한다. 하지만 async는 스코프가 필요하고 GlobalScope 사용은 좋은 방법이 아니다. GlobalScope에서 async를 호출하면 아래 결과가 발생한다. 메모리 누수가 발생할 수 있고 쓸데없이 CPU를 낭비함 코루틴을 단위 테스트하는 도구가 작동하지 않아서 함수 테스트가 어려움 따라서 위 방법 대신 스코프를 인자로 넘..
잡히지 않은 예외가 발생하면 앱이 종료되듯 코루틴도 종료된다. 쓰레드도 종료되지만 차이가 있다면 코루틴 빌더는 부모도 종료시키고 취소된 부모는 모든 자식을 취소시킨다는 것이다. 아래 예에선 예외를 받았을 때 자신을 취소하고 launch가 예외를 부모로 전파한다. import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main(): Unit = runBlocking { launch { delay(1000) throw Error("에러 발생") } launch { delay(2000) println("여기는 출력되지 않음") } launch { delay(500) // 예외..
코루틴의 가장 중요한 기능 중 하나는 취소다. 취소는 정말 중요한 기능이라 중단 함수를 쓰는 몇몇 클래스, 라이브러리는 반드시 지원한다. 단순히 쓰레드를 죽이면 연결을 닫고 해제하는 기회가 없어서 최악의 취소 방식이라고 볼 수 있다. 상태가 여전히 Active인지 확인하는 것도 불편하다. 코루틴이 제시하는 방식은 아주 간단하면서 안전하다. 기본적인 취소 Job 인터페이스는 취소하게 하는 cancel()을 가졌다. 이걸 호출하면 아래 효과를 볼 수 있다. 호출한 코루틴은 첫 중단점(아래 코드에선 delay())에서 Job을 끝냄 Job이 자식을 가졌다면 그 자식들도 취소되지만, 부모는 영향받지 않음 Job이 취소되면 Job은 새 코루틴의 부모로 쓰일 수 있음. 취소된 Job은 Cancelling 상태가 됐..
구조화된 동시성의 중요 특징 3개는 Job 컨텍스트와 관련 있다. Job은 코루틴 취소, 상태 파악 등 여러 곳에서 다양하게 쓰일 수 있다. Job이란 Job은 수명을 갖고 있고 취소할 수 있다. Job은 인터페이스지만 구체적 사용법, 상태를 갖고 있어서 추상 클래스처럼 다룰 수 있다. 아래는 Job의 수명을 나타낸 그림이다. Active 상태에선 Job이 실행되고 코루틴은 Job을 수행한다. Job이 코루틴 빌더에 의해 생성됐을 때 코루틴 본체가 실행되는 상태다. 이 때 자식 코루틴을 실행할 수 있고 대부분의 코루틴은 Active 상태로 시작한다. 지연 시작되는 코루틴만 New 상태에서 시작한다. New 상태인 코루틴이 Active 상태가 되려면 작업이 실행돼야 한다. 코루틴이 본체를 실행하면 Acti..
launch의 정의를 보면 첫 파라미터가 coroutineContext인 걸 알 수 있다. public fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend CoroutineScope.() -> Unit ): Job 마지막 인자의 리시버도 CoroutineScope다. 이것은 중요한 개념 같으니 시그니처를 확인한다. public interface CoroutineScope { public val coroutineContext: CoroutineContext } @SinceKotlin("1.3") public ..
중단 함수는 Continuation 객체를 다른 중단 함수로 보내야 하기 때문에 아래가 성립한다. 중단 함수는 일반 함수를 호출할 수 있다 일반 함수는 중단 함수를 호출할 수 없다 때문에 모든 중단 함수는 다른 중단 함수에 의해 호출돼야 한다. 그렇다고 일반 함수에서 아예 중단 함수를 호출할 수 없는 건 아니다. 코루틴 빌더를 통해 일반 함수 안에서 중단 함수를 호출할 수 있다. 코루틴 빌더는 3종류 있고 서로 쓰임새가 다르다. launch runBlocking async launch launch의 작동 방식은 thread 함수를 호출해 새로운 쓰레드를 시작하는 것과 같다. import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay imp..
중단 함수(suspend fun)는 코루틴의 핵심으로, 중단이 가능하다는 건 코루틴의 다른 모든 개념의 기본이 된다. 코루틴은 중단되면 Continuation 객체를 리턴하는데 이 객체를 쓰면 멈췄던 곳에서 코루틴을 재시작할 수 있다. 또한 코루틴을 중단할 때 어떤 자원도 쓰지 않으며 다른 쓰레드에서 시작하거나 (역)직렬화할 수 있다. 재개 재개에는 당연히 코루틴이 필요하다. 이것은 안드로이드 디벨로퍼에도 작성되어 있으며 해당 링크는 하단의 재개 부분에 첨부했다. 중단 함수는 반드시 코루틴 or 다른 중단 함수에 의해 호출돼야 한다. 코루틴은 runBlocking, launch 같은 코루틴 빌더를 써서 만들 수 있다. suspend fun main() { println("before") println("..
파이썬, 자바스크립트 등 언어에선 제한된 형태의 코루틴을 쓰고 있다. 비동기 함수(async, await) 제너레이터 함수(값을 순차적으로 리턴하는 함수) 코틀린에는 제너레이터 대신 시퀀스를 생성할 때 사용하는 시퀀스 빌더가 있다. 시퀀스는 List, Set 같은 컬렉션과 비슷한 개념이지만 필요할 때마다 값을 하나씩 계산하는 지연 처리를 한다. 시퀀스의 특징은 아래와 같다. 요구되는 연산을 최소한으로 수행 무한정이 될 수 있음 메모리 사용이 효율적 (이펙티브 코틀린 아이템 49 참고) 이런 특징 때문에 값을 순차 계산해서 필요할 때 리턴하는 빌더를 정의하는 게 좋다. 시퀀스는 sequence 함수로 정의하며 람다식 안에선 yield 함수를 호출해 시퀀스의 다음 값을 생성한다. val seq = seque..
안드로이드에서 비동기적으로 연산하는 방법은 여럿 있다. RxJava, Reactor 등의 JVM 계열 라이브러리 사용 자바 자체적으로 지원하는 멀티 쓰레드 콜백 함수 그럼 왜 코루틴을 배워야 할까? 코루틴은 기존 방식들보다 많은 걸 지원한다 1963년에 처음 소개된 논문에서의 기능을 실생활에서도 유용하게 쓸 수 있도록 라이브러리로 만들어짐 코틀린을 쓰는 모든 플랫폼(JVM, JS, iOS, 다른 모듈들)에서 사용할 수 있다(멀티 플랫폼) 안드로이드에서의 코루틴 사용 프론트엔드에서 앱 로직을 구현할 때 가장 흔하게 쓰는 방법은 하나 or 다양한 소스(api, 뷰 컴포넌트, DB, 설정, 다른 앱)로부터 데이터를 가져옴 데이터 가공 가공된 데이터로 뭔가를 함(뷰에 표시, DB에 저장, api로 전송 등) a..