Inflearn brand logo image

인프런 커뮤니티 질문&답변

장대영님의 프로필 이미지
장대영

작성한 질문수

2시간으로 끝내는 코루틴

2강. 스레드와 코루틴

Coroutine과 ThreadLocal관련 질문

작성

·

85

·

수정됨

0

안녕하세요 선생님, 강의 정말 잘 듣고 있습니다. 한가지 강의를 들으면서 궁금한 점이 생겨 질문 드립니다.

설명해주신 내용을 들었을 때, 코루틴은 특정 스레드와 종속적인 관계가 아니기 때문에 여러 스레드에 걸쳐 실행될 수 있다고 말씀해주셨습니다.

"코루틴1의 코드1은 스레드1에서 실행되었지만, 코루틴1의 코드2는 스레드2에서 실행되었다!"

그런데 아래의 예시의 경우에는 문제가 존재할지 궁금합니다.

  1. 스레드1에서 코루틴1의 코드1은 ThreadLocal을 만들어 사용하다가 중단 지점에 걸려 멈췄습니다.

  2. 그 후에 코루틴1의 코드2가 실행될 때, 스레드2에서 실행되었습니다.

  3. 코드2에는 코드1에서 만든 ThreadLocal을 가져다 쓰는 경우

스레드1에 종속적인 ThreadLocal을 스레드2에서 가져다 쓸 경우 문제가 발생할 것 같은데.. (1)코루틴에서 ThreadLocal을 사용하는 것은 안티패턴으로 취급될까요?

이보다 좀 더 근본적인 질문으로 돌아가서 (2)코루틴을 사용할 때 ThreadLocal을 사용하는 게 자주 있는 일일까요?

답변 2

1

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요! 대영님~ 좋은 질문 감사드립니다.

먼저, 말씀해주신 문제는 충분히 생길 수 있는 문제입니다. 때문에 코루틴에서 ThreadLocal을 그냥 사용하는 것은 코드가 의도한대로 동작하지 않을 수 있어요! (1) 그런 관점에서 안티패턴 혹은 의도와 다른 동작 이라고 볼 수 있을 것 같습니다.

 

(2) 또한 코루틴을 사용할 때 ThreadLocal을 직접적으로 사용하는 경우는 많이 없습니다. 하지만 간혹 프레임워크에서 ThreadLocal로 관리되는 변수에는 접근해야 할 일이 있는데, (서버 개발자 이신 경우...) Slf4j MDC가 대표적인 것 같습니다.

로깅에서 특정한 traceId를 활용하기 위해 Filter 같은 곳에서 MDC.set("traceId", 일정한 난수) 를 수행했다고 해보죠! 그리고 나서 코루틴에 들어가 로직이 실행되는데, 이 안에서 로그를 찍으면 traceId 가 함께 나와야 하는거에요!

MDC는 내부적으로 ThreadLocal을 사용해 traceId와 같이 입력된 필드를 저장하기 때문에 말씀해주신 흐름에 따라 코루틴에서는 로그가 제대로 추적되지 않을 수 있습니다. 이런 경우 CoroutineContext를 이용하실 수 있는데요~ 스레드가 변경되더라도 일련의 실행 흐름을 추적할 수 있는 context를 구성하는 방식입니다. 코루틴은 MDC에 대해서 라이브러리 형태로 제공하고 있기에 아래 의존성을 추가하신 후

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-slf4j:1.9.0")

runBlocking(MDCContext()) 처럼 코루틴 세계에 진입하는 지점에 MDCContext() 를 적어주기만 하면 ThreadLocal로 관리되고 있던 변수들을 CoroutineContext로 옮겨와 관리할 수 있도록 됩니다. 🙂

(이 기능의 내부 원리가 CoroutineContext의 Element를 관리하는 것 이고요..! ThreadContextElement를 찾아보셔도 좋습니다!) 참고로, 이런 방식은 spring webflux도 필요합니다.

 

답변이 도움이 되었으면 좋겠습니다. 감사합니다. 🙇

장대영님의 프로필 이미지
장대영
질문자

궁금했던 점이 싹 풀렸습니다 ㅎㅎ 정말 감사합니다!!

0

안녕하세요, 인프런 AI 인턴입니다. 장대영님.

코루틴과 ThreadLocal 관련하여 좋은 질문 주셨습니다. 코루틴에서는 특정 스레드와의 독립성이 큰 특징인데, 이를 ThreadLocal과 함께 사용할 때의 문제가 있을 수 있습니다. 관련하여 비슷한 질문과 답변을 참고할 수 있는 몇 가지 링크를 제공해 드리겠습니다.

먼저, 코루틴 내에서 ThreadLocal 사용은 일반적으로 안티패턴으로 분류됩니다. 그 이유는 코루틴은 하나의 스레드에 종속되지 않기 때문에, 여러 스레드에 걸쳐 실행될 수 있습니다. 아래 링크에서 스레드 간의 독립성 문제와 이에 대한 해법들이 다루어지고 있습니다:

  • 코루틴 dispatcher IO관련 질문: 이 질문에서는 Dispatcher와 스레드의 특성에 대한 논의가 있습니다. 비슷한 문제가 여기서도 연상될 수 있습니다.

  • 코루틴의 대한 질문이 있습니다.: 코루틴의 실행 흐름에 대해 다루고 있습니다. 이론상 코루틴은 개별 스레드 상태에 의존하지 않고 설계되므로, ThreadLocal 사용 시 주의가 필요합니다.

ThreadLocal은 코루틴의 특성과 맞지 않는 경우가 많습니다. 코루틴은 여러 스레드에 걸쳐 작동할 수 있기 때문에, 각 스레드의 로컬 변수를 안전하게 관리할 필요가 있는 경우 ThreadLocal 대신 코루틴 컨텍스트나 다른 메커니즘을 고려해야 합니다.

코루틴을 사용할 때 ThreadLocal 사용은 거의 드물며 피하는 것이 좋습니다. 여러 스레드의 일관성을 유지하기 어려울 수 있기 때문입니다. 대신, 코루틴의 컨텍스트를 통해 상태를 관리하는 것이 좋은 대안이 될 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.

현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

장대영님의 프로필 이미지
장대영

작성한 질문수

질문하기