본문 바로가기

Kotlin/kotlinx.coroutines

CopyableThreadContextElement

📌 Kotlin Coroutines의 CopyableThreadContextElement 이해하기

1. 개요

CopyableThreadContextElementThreadContextElement를 확장한 인터페이스로, 자식 코루틴이 해당 컨텍스트를 상속할 때마다 복사됩니다. 이는 ThreadLocal을 사용하는 API에서 코루틴이 "코루틴 안전"하게 ThreadLocal에 쓰기 작업을 수행할 수 있도록 합니다.

2. 주요 기능

  • 코루틴별 쓰기 격리: 코루틴이 CopyableThreadContextElement를 통해 ThreadLocal에 쓰기를 수행하면, 해당 코루틴과 이후에 시작된 자식 코루틴에서만 그 값을 볼 수 있습니다. 부모 코루틴, 동료 코루틴, 또는 동일한 스레드를 사용하는 다른 코루틴에서는 이 값을 볼 수 없습니다.
  • 구조적 동시성 지원: 코루틴이 구조적 동시성을 유지하면서도 가변적인 ThreadLocal API를 투명하고 올바르게 사용할 수 있도록 합니다.

3. 사용 예시

다음은 메서드 추적을 위해 ThreadLocal을 "코루틴 로컬"로 변환하는 예시입니다:


class TraceContextElement(private val traceData: TraceData?) : CopyableThreadContextElement<TraceData?> {
    companion object Key : CoroutineContext.Key

    override val key: CoroutineContext.Key = Key

    override fun updateThreadContext(context: CoroutineContext): TraceData? {
        val oldState = traceThreadLocal.get()
        traceThreadLocal.set(traceData)
        return oldState
    }

    override fun restoreThreadContext(context: CoroutineContext, oldState: TraceData?) {
        traceThreadLocal.set(oldState)
    }

    override fun copyForChild(): TraceContextElement {
        // 자식 코루틴이 시작될 때 ThreadLocal의 현재 값을 복사합니다.
        return TraceContextElement(traceThreadLocal.get()?.copy())
    }

    override fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext {
        // 병합 작업은 부모 코루틴과 자식 코루틴 모두에 동일한 키를 가진 요소가 있을 때 처리 방법을 정의합니다.
        return TraceContextElement(traceThreadLocal.get()?.copy())
    }
}

위의 예시에서, 코루틴은 이 메커니즘을 사용하여 해당 스레드 로컬 요소의 값이 대상 스레드 로컬에 설치되었다고 가정하는 Java 코드를 안전하게 호출할 수 있습니다.

4. 재진입성과 스레드 안전성

이 인터페이스의 올바른 구현은 restoreThreadContext 호출이 이후의 updateThreadContextrestoreThreadContext 작업과 병렬로 발생할 수 있음을 예상해야 합니다. 따라서 모든 CopyableThreadContextElement의 구현은 스레드 안전해야 하며, 요소 내의 내부 가변 상태를 적절히 보호해야 합니다.

📌 원본 출처

본 문서의 내용은 Kotlin 공식 문서를 참고하여 작성되었습니다. 자세한 내용은 아래 공식 문서를 통해 확인할 수 있습니다.

🔗 Kotlin Coroutines 공식 문서 - CopyableThreadContextElement

'Kotlin > kotlinx.coroutines' 카테고리의 다른 글

CoroutineDispatcher  (0) 2025.02.07
CopyableThrowable  (0) 2025.02.07
CompletionHandler  (0) 2025.02.07
completeWith  (0) 2025.02.07
CompletableJob  (0) 2025.02.07