[TIL]230408 - 동시성 문제와 thread local

insightp25·2023년 4월 8일

동시성 문제

여러 스레드가 동시에 같은 인스턴스의 필드 값을 변경하면서 발생하는 문제를 흔히 '동시성 문제'로 일컫는다.

  • 특징: 여러 스레드가 같은 인스턴스의 필드에 접근해야 하기 때문에 트래픽이 적은 상황에서는 확률상 잘 나타나지 않고, 트래픽이 점점 많아질 수록 자주 발생

  • 특히 스프링 빈 처럼 싱글톤 객체의 필드를 변경하며 사용할 때 이런 동시성 문제를 조심해야 한다.

  • 당연히도 동시성 문제는 스레드마다 각각 다른 메모리 영역이 할당되는 지역 변수에서는 일어나지 않는다.

    • 인스턴스의 필드(주로 싱들톤에서 자주 발생), 또는 static 같은 공용 필드에 접근할 때 발생한다.
  • 동시성 문제는 값을 읽기만 하면 발생하지 않는다.
    (파라미터를 전달하는 방식도 OK)

스레드 로컬thread local

스레드 로컬은 싱글톤 객체의 필드를 사용하면서 동시성 문제를 해결하는 방법들 중 하나이다.

  • 스레드 로컬 사용 시 각 스레드마다 해당 스레드만 접근할 수 있는 특별한 내부 저장소를 별도 제공한다.
    • 같은 인스턴스의 스레드 로컬 필드에 접근해도 문제 없다.

  • 자바는 언어 차원에서 스레드 로컬을 지원하기 위해 java.lang.ThreadLocal 클래스를 제공한다.
  • 사용법
    • 값 저장: ThreadLocal.set(OOO)
    • 값 조회: ThreadLocal.get()
    • 값 제거: ThreadLocal.remove()

주의 사항

스레드 로컬 사용 후 스레드 로컬에 저장된 값은 반드시 제거해 주어야 한다. 제거하지 않을 시 WAS(톰캣) 처럼 스레드 풀을 사용하는 경우 심각한 문제가 발생할 수 있다.

  • 예:
    1. 사용자 A가 요청을 하였고 WAS는 스레드 풀에서 스레드1을 꺼내와 사용하고 스레드 로컬을 제거하지 않은 채 스레드1을 반납하였다.
    2. 이후 사용자 B의 다른 개별 요청이 들어왔고 해당 요청이 스레드1에 다시 할당되었다.
    3. 여기서 스레드1이 필드 조회를 할 시 스레드1 전용 보관소로부터 예전에 썼던 사용자 A의 데이터를 불러와 조회하는 심각한 오류가 생긴다.

reference

profile
backend, data-streaming, AI

0개의 댓글