- runBlocking : 일반루틴 세계와 코루틴 세계를 연결한다. {} 괄호안에 있는 것들은 코루틴
- launch : 반환값이 없는 코루틴을 만든다. 만들어 놓은 코루틴을 바로 실행시키지 않는다.
- yield : 지금 코투린을 중단하고, 다른 코루틴이 실행되도록 한다 ( 스레드를 양보한다)
- suspend fun : 다른 suspen fun을 호출할 수 있다.
프로세스가 스레드보다 큰 개념이듯이, 스레드가 코루틴 보다 큰 개념이다
코루틴은 코루틴이 직접 코드를 실행시키는게 아니라 가지고 있는 코드를 스레드에 넘겨서 실행한다
코루틴은 스레드에 종속적이지 않아 중단 되었다가 재개될 때 다른 스레드에 배정될 수 있다.
스레드: heap메모리를 공유하고, Stack만 교체되므로 프로세스보다 비용이 적다
코루틴: 동일 스레드에서 실행되면, 같은 heap메모리, stack을 공유하므로 context switching 비용이 낮다.
-> 하나의 스레드에서 동시성을 확보할 수 있다.
반환값이 없는 코루틴을 만든다. 여기서 반환된 값은 반환값이 아니라 이 코루틴을 컨트룰할 수 있는 객체임.
start() : 시작
cancel() : 취소
join() : 해당 코루틴이 완료될 때까지 대기
async(Lazy옵션) : 계산결과를 기다리고 넘어감.
-> async라 동시에 시작하는게 아니라 job1기다리고 그 값이나오면 job2실행
start() 함수를 한번 호출해주면 다시 괜찮아진다.
yield 나 delay 처럼 suspend 함수를 사용해야함
suspend 함수를 사용하지 않는경우 무한루프에 걸릴수 있다.
delay() / yield() 와 같은 kotlinx.coroutines 패키지의 suspend 함수를 사용해야 한다.
코루틴 스스로 본인의 상태를 확인해 취소 요청을 받았으면, CancellationException을 던져야함
delay(), /yield() 는 이미 CancellationException을 던져 그걸로 취소시키는데 try-catch로 잡아버리면 취소가 안됌
isActive를 통해 현재 코루틴이 활성화 되어있는지, 취소 신호를 받았는지 확인 가능
launch(Dispatchers.Default) 를 사용하면 lauch안에 있는 코드는 다른 스레드에게 실행시킨다.
lauch 는 예외발생시 예외를 읽고 코루틴을 멈추지만 async는 예외를 뱉지 않음, await로 찍어야 예외 터짐
root 코루틴이 아닌, 자식 코루틴에서 예외가 터질경우 부모 코루틴까지 전파 시키기 때문에 async를 사용해도 예외 발생함
자식 코루틴에서 예외 전파 안하려면 async(SupervisorJob())사용
lauch 안에 있는 예외를 try-catch로 잡으면 코루틴이 종료되지 않고 진행된다.
에러를 로깅, 메세지 전파, 공통된 로직을 사용하고 싶으면 CoroutineExceptionHandler 사용 -> 이 핸들러는 launch()에만 적용 가능하며 부모 코루틴이 있으면 동작하지 않는다.
-> 큰 차이점은 try-catch를 사용시 예외가 발생 하지 않은것처럼 간주된다는, Handler는 사용하면 로깅 찍히니까
발생한 예외가 CancellationException인 경우 취소로 간주하고 부모 코루틴에게 전파 x
다른 예외는 실패로 간주하고 부모 코루틴에게 전파
-> 둘다 내부적으로는 취소됨 으로 간주, 차이점은 부모에게 전파하느냐 안하느냐
첫번째 사진에서는 1번자식 코루틴이 일을 먼저 끝내고 2번자식에서 예외가 발생 -> 부모 전파 == 1번은 성공
두번째 사진에서는 2번째 자식에서 먼저 실패 -> 부모 예외 전파 -> 자식루틴에게 취소명령내림 == 둘다 실패
-> 이렇게 한몸처럼 움직이는것을 Structured Concurrency라고 한다
-> 자식 코루틴에서 예외가 발생하지 않더라도 부모 코루틴이 취소되면 자식 코루틴들도 취소 된다!!
-> CaccellationException은 정상적인 취소로 간주하기 때문에 부모 코루틴에게 전파되지 않고, 부모 코루틴의 다른 자식 코루틴을 취소시키지 않는다.
launch, async는 CoroutineScope의 확장 함수 이다. 즉 runBlocking이 CoroutineScope를 제공해 준다.
우리가 CoroutineScope를 만들면 runBlocking은 필요하지 않다.
코루틴과 관련된 데이터, 코루틴 이름, 코루틴 그 자체 ,CoroutineExceptionHanlder, CoroutineDispatcher 을 가지고 있다.
Map+Set을 합쳐놓은 상태,( key-value이면서 같은 key의 데이터는 유일함)
key-value를 element라고 하며 서로 합칠 수 도 있다.
종류
- coroutineScope는 async나 launch 처럼 start를 기다리지 않고 블록이 바로 실행 된다.