묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결2시간으로 끝내는 코루틴
자식1, 2와 부모코루틴의 관계
본 강의를 모두 수강하였습니다! 코루틴에서 헷갈렸던 개념들을 알 수 있어서 좋았습니다!본 코루틴 강의에서 자식과 부모 관계의 에러가 발생했을 때 에러 핸들링 하는 경우는 자식이 하나만 존재했을 때의 예시밖에 없어서 직접 2개를 가지고 실험을 해보았습니다! 먼저, 자식1이 취소가 됐을 때에는 취소예외가 발생했기 때문에 부모로 전파되지 않고, 그러므로 다른 자식2도 영향을 받지 않는다 라고 이해를 하고 있습니다!하지만 자식1에서 취소가 아닌 예외가 발생했을 경우 부모로 전파되는 것으로 알고있고, 이 때 적절한 조치가 되지 않는다면 자식2까지 취소되는 것으로 알고있습니다!따라서 다음과 같이 CoroutineExceptionHandler를 적용해보았습니다.fun main() = runBlocking { val handler = CoroutineExceptionHandler { _, exception -> println("Caught exception: $exception") } val parentJob = CoroutineScope(Dispatchers.Default).launch(handler) { val job1 = launch { println("Job 1 is running") throw RuntimeException("Error in Job 1") } val job2 = launch { println("Job 2 is running") delay(1000) println("Job 2 is completed") } job1.join() job2.join() } parentJob.join() println("Parent job is completed") }Job 1 is runningCaught exception: java.lang.RuntimeException: Error in Job 1Parent job is completed결과는 자식1만 실행이되고, 거기서 Exception을 던졌는데, Job2는 취소되는것으로 보입니다..!질문 1 ) 다음과 같이 try catch 로 전환하면 자식2의 취소가 발생하지 않는데, CoroutineExceptionHandler로는 자식2의 취소를 막을수는 없는 것일까요?val job1 = launch { println("Job 1 is running") try { throw RuntimeException("Error in Job 1") } catch (e: RuntimeException) { println("RuntimeException") } }질문 2) 강의내용에서는 SupervisorJob() 을 사용하면 부모 코루틴으로 예외가 전파되지 않는다고 해주셨는데, 다음 결과에서는 부모코루틴에 해당되는 CoroutineExceptionHandler 가 실행되는 것으로 보입니다. 하지만, 질문1에서 걱정하는 자식2의 취소로 이어지지 않고 있습니다. 이는 부모코루틴으로 예외가 전파되는 상황일까요?? 만일 전파되는 상황이라면 왜 질문1과는 다르게 자식2의 취소로 이어지지 않는 것일까요?fun main() = runBlocking { val handler = CoroutineExceptionHandler { _, exception -> println("Caught exception: $exception") } val parentJob = CoroutineScope(Dispatchers.Default).launch(handler) { val job1 = launch(SupervisorJob()) { println("Job 1 is running") throw RuntimeException("Error in Job 1") } val job2 = launch { println("Job 2 is running") delay(1000) println("Job 2 is completed") } job1.join() job2.join() } parentJob.join() println("Parent job is completed") }Job 1 is runningJob 2 is runningCaught exception: java.lang.RuntimeException: Error in Job 1Job 2 is completedParent job is completed자바 -> 코틀린 강의부터 시작해서 코루틴 강의까지 너무 감사하게 잘 보고있습니다! 감사드립니다 🙂
-
해결됨2시간으로 끝내는 코루틴
한 suspend fun 의 반환값이 다른 suspend fun의 파라미터로 쓰일 때
fun main(): Unit = runBlocking { val job1 = async { apiCall1() } val job2 = async { apiCall2(job1.await()) } printWithThread(job2.await()) } suspend fun apiCall1(): Int { delay(1_000L) return 1 } suspend fun apiCall2(num: Int): Int { delay(1_000L) return num + 2 }위와 같은 코드에서, 코루틴을 사용해도 apiCall1() 의 반환값이 apiCall2()의 인자로 사용되기 때문에, apiCall1()이 완료된 후에 apiCall2()가 실행되는 것은 이해했습니다. 그리고 코루틴을 사용할 때의 이점이 마치 한줄한줄 동기식 코드를 작성할 때처럼 비동기 코드를 사용할 수 있다. 로 이해했습니다.그럼 위와 같은 상황에서는 굳이 코루틴을 사용하지 않고, 아래와 같이 동기적으로 코드를 작성해도 같은 것일까요? (두 apiCall1,2를 사용하는 외부 메서드가 없을 때)fun main() { val job1 = apiCall1() val job2 = apiCall2(job1) printWithThread(job2) } fun apiCall1(): Int { delay(1_000L) return 1 } fun apiCall2(num: Int): Int { delay(1_000L) return num + 2 }비동기 처리가 처음이다 보니 직관적으로 잘 와닿지 않는 부분이 많아 자꾸 질문드리네요 ㅜㅜ 죄송합니다.
-
해결됨2시간으로 끝내는 코루틴
delay 함수에 대해 질문이 있습니다
강의 듣던 와중 delay에 대한 궁금증이 생겨서 질문드립니다.만약 한 코루틴에서 delay로 시간을 전부 보낸 후에는 작업 중인 다른 코루틴에게서 제어권을 뺏어오게 되나요?아래와 같은 예시에서fun main(): Unit = runBlocking { val job1 = launch { delay(100) printWithThread("Job 1") } val job2 = launch { // 대충 0.1초보다 더 걸리는 로직 } }위와 같은 상황에서는job1에서 delay로 0.1초 기다림과 동시에 job2에게 넘겨줌job2 실행중job1에서 기다리기로 약속한 0.1초 지남하지만 job2 아직 실행중이 상황에서는 job2의 로직이 전부 끝난 후에 job1에게 제어권을 넘겨주게 되는 걸까요?
-
해결됨2시간으로 끝내는 코루틴
runBlocking을 사용하는 경우가 있을까요?
안녕하세요, 좋은 강의 잘 듣고 있습니다.runBlocking 설명하시면서, runBlocking은 자신의 코루틴이 모두 실행될 때까지 Thread를 Blocking 시킨다. 그래서 main 함수 최초 진입점이나, 테스트 코드 맨처음에 작성하는 것이 좋다. 라고 말씀해 주셨습니다.그런데 그럼 테스트 코드 전체 또는 main 함수 전체를 코루틴으로 작성할 경우에만 사용이 되는 걸까요? 테스트 코드 이외에는 실제 로직에서 어떤 경우에 사용이 될지 궁금합니다.아직 강의 초반부라서 이해가 부족한 것인가 싶기도 하지만 실시간으로 궁금해서 여쭤봅니다.
-
미해결2시간으로 끝내는 코루틴
delay가 없으면 실행 안 되는 이유
안녕하세요! 좋은 강의 잘 듣고 있습니다.😄5강 수강 중인데, 여기에서 fun lec05Example2(): Unit = runBlocking { val job = CoroutineScope(Dispatchers.Default).launch { throw IllegalArgumentException() } delay(1_000L) }delay(1_000L) 부분이 없으면 위의 예외 던지는 코루틴을 실행을 안 하던데 왜 그런지 이유를 잘 모르겠습니다.
-
미해결2시간으로 끝내는 코루틴
코루틴 스코프
코드를 보다보면 코루틴 스코프를 쓸 때, 소문자로 coroutineScope { } 블락이 있는 경우가 있고 대문자로 시작하는 CoroutineScope(Dispatchers.Main).launch { } 이런식으로 된 코루틴스코프가 있는데, 각각 어떤 차이이며 어느 상황에 각각을 써야하나요?
-
미해결2시간으로 끝내는 코루틴
CoroutineScope 와 withContext 의 차이를 잘 모르겠습니다.
강의를 듣다보면 CoroutineScope 와 withContext 의 차이를 정확히 모르겠습니다. withContext 는 context 에 변화를 줄 수 있어서 withContext(Dispatchers.Default) 이런 식으로 쓴다고 하는데, CoroutineScope 도 동일하게 CoroutineScope(Dispatchers.Default).launch 이런식으로 context 를 설정해줄 수 있는데 어떨 때 CoroutineScope 를 쓰고 어떨 때 withContext 를 쓰는지 잘 모르겠습니다.
-
해결됨2시간으로 끝내는 코루틴
Dispatchers 관련 궁금증입니다.
withContext(Dispatchers.IO) { println(“AA : ${Thread.currentThread().name}") val asyncOrigin = async { println(“BB : ${Thread.currentThread().name}") origin.invoke() }} // 결과AA : DefaultDispatcher-worker-1 @coroutine#2BB : DefaultDispatcher-worker-3 @coroutine#3 안녕하세요.Dispatchers 사용부분이 궁급함니다. 따로 asyncOrigin에서 Dispatchers를 다르게 쓰겠다고 설정한게 없는데 결과가 의문이였습니다. 물론 코루틴은 각자 실행이여서 코루틴의 번호가 다른건 이해했습니다만,부모꺼의 스레드를 가져다 쓸거다라고 생각했는데 스레드도 부모꺼를 안쓰고 다른게 맞는걸까요?어떤 원리인지 궁금합니다.
-
해결됨2시간으로 끝내는 코루틴
yield 함수가 없어도 결과가 동일한 이유가 뭔가요?
yield 함수를 지워도 실행을 했을 때 출력 순서가 동일한 이유가 궁금합니다!runBlocking 으로 실행한 코루틴과 launch 로 실행한 코루틴의 순서가 변경됐던 이유가 yield 때문이 아니기 때문일까요?
-
해결됨2시간으로 끝내는 코루틴
코루틴 Job 상속에 관하여 질문드려요
안녕하세요 강사님~ 좋은 강의 너무 감사드립니다. 덕분에 코루틴 입문을 쉽게 할 수 있었습니다.다름이 아니라 강사님 강의를 완강하고나서 코루틴 관련 책을 보고 있는데요,Job은 자식에게 상속되지 않는 유일한 코루틴 컨텍스트라는 내용이 있네요.이곳저곳 더 찾아보니 부모 코루틴을 기반으로 고유한 Job을 갖는다는 내용이 있는데 정확히 이게 어떤 의미인지 모르겠어서 질문을 드립니다!
-
미해결2시간으로 끝내는 코루틴
코루틴 취소 관련 질문
fun main(): Unit = runBlocking { val job = launch { var i = 1 var nextPrintTime = System.currentTimeMillis() while (i <= 5) { if(nextPrintTime <= System.currentTimeMillis()){ printWithThread("${i++}번째 출력!") nextPrintTime += 1_000L } } } delay(100L) job.cancel() }수업 때 예시로 보여주신 코드인데 이 코드는 "5번째 출력!"까지 출력하고 끝이 나는데요. 반면에 아래 코드는 한번만 출력하고 끝이 납니다.fun main(): Unit = runBlocking { val job = launch { var nextPrintTime = System.currentTimeMillis() repeat(5) { if (nextPrintTime <= System.currentTimeMillis()) { printWithThread("${it + 1}번째 출력!!") nextPrintTime += 1_000L } } } delay(100L) job.cancel() }이는 단순히 repeat문이 무한루프가 아니어서 나오는 차이일까요?
-
미해결2시간으로 끝내는 코루틴
single thread에서 여러개의 co-routine ( 각각 서버연동을 수행 ) 을 순차적이 아닌 concurreny 하게 수행하게 할방법은 없나요?
single thread에서 여러개의 co-routine ( 각각 서버연동을 수행 ) 을 순차적이 아닌 concurreny 하게 수행하게 할방법은 없나요? 상황Single Thread ㄴ co-routine (1) : 서버연동 ( 사용자 정보를 요청 )ㄴ co-routine (2) : 서버연동 ( 회원등급 정보 요청) 테스트 결과co-routine (1)이 실행완료 -> co-routine(2) 수행 동시적으로 서버에 요청하지 않음 CoroutineScope(Dispatchers.Default)로 설정하여 각각 쓰레드를 생성하면 동시적으로 수행되나,이럴경우 co-routine을 사용해야 되는 의미가 필요한지 의문이 생김결국 multi thread가 발생했다는건 context swiching이 발생한다는 뜻인데. 오히려 이럴 바에는 co-routine을 사용하지 않고 multi thread만 사용해서 해당 코드를 수행하는것고 어떤 차이가 있는지잘 모르겠습니다.제 의문에 대한 명쾌한 대답을 듣고 싶습니다.
-
미해결2시간으로 끝내는 코루틴
suspend function의 일시 중단 여부는 어떻게 결정되나요?
안녕하세요 강사님, 좋은 강의에 항상 감사드리고 있습니다! 다른게 아니라, 강의 중 suspend function은 일시 중단 되었다가 재개될 수도 있고 / 그렇지 않을 수도 있다고 설명 주셨습니다. 그렇다면 실제로 suspend function이 일시 중단되어야 하는지 여부는 어떻게 결정되나요?단순히 suspend function 내부에서 또 다른 suspend function을 호출하기만 하면 무조건 일시 중단 되는 것인지, 아니면 Node.js 진영의 libuv 라이브러리처럼 비동기적으로 처리되어야 하는 IO 작업을 내부적으로 인지하는 방식이 별도로 구현되어 있는지 궁금합니다!
-
미해결2시간으로 끝내는 코루틴
코루틴이 자바 reactive streams 대신에 쓸 수 있는 것일까요?
추후에 자바 프로젝트를 코틀린으로 컨버팅할 계획을 가지고 있는데 자바의 비동기 라이브러리인 reactive streams를 코루틴이 대체할 수 있을까 해서요
-
해결됨2시간으로 끝내는 코루틴
코루틴과 스레드로컬 동시 사용은 실무에서 지양되나요?
공식문서에서 asContextElement 메소드 등을 통해 서로 다른 스레드에 할당되는 코루틴들이 동일한 스레드 로컬을 바라볼 수 있는 기능이 제공된다는 것은 확인했습니다 그런데 웹상에서나 사내 코드상에서나 사용되는 케이스가 별로 없네요.. 혹시 강사님은 많이 사용하시나요? 🙋🏿♂️(전 코루틴 컨텍스트를 통해 부모 자식간에 데이터를 공유할줄 알았는데 아닌가보네요..)
-
미해결2시간으로 끝내는 코루틴
프로젝트 세팅값좀 알려주세요
프로젝트 생성하는 장면이 없네요;;사용하고 계시는 gradle 버전, kotlin compiler 버전 등을 알려주세요intellij 버전은 2021.2.1 을 쓰고있고, 강의의 build.gradle.kts 사용 시아래같은 에러가뜹니다. Some Kotlin libraries attached to this project were compiled with a newer Kotlin compiler and can`t be read. please update Kotlin plugin . No updates found