Thread Local

...·2024년 8월 12일

spring

목록 보기
5/6

Thread Local

쓰레드 로컬은 해당 쓰레드만 접근할 수 있는 특별한 저장소를 말한다. 쉽게 말해서 물건 보관 창구를 생각하면 된다. 여러 사람이 같은 물건 보관 창구를 사용하더라도 창구 직원은 사용자를 인식해서 사용자별로 확실하게 물건을 구분해준다.

일반적인 변수 필드

여러 쓰레드가 같은 인스턴스의 필드에 접근하면 처음 쓰레드가 보관한 데이터가 사라질 수 있다.

쓰레드 로컬

쓰레드 로컬을 사용하면 각 쓰레드마다 별도의 내부 저장소를 제공한다. 따라서 같은 인스턴스의 쓰레드 로컬 필드에 접근해도 문제 없다.

예를 들어, thread-A가 userA라는 값을 저장하면 쓰레드 로컬은 thread-A 전용 보관소에 데이터를 안전하게 보관한다.
마찬가지로 thread-B가 userB라는 값을 저장하면 쓰레드 로컬은 thread-B 전용 보관소에 데이터를 안전하게 보관한다.

주의사항

쓰레드 로컬의 값을 사용 후 제거하지 않고 그냥 두면 WAS처럼 쓰레드 풀을 사용하는 경우에 심각한 문제가 발생할 수 있다.

요청

  1. 사용자 A가 저장 HTTP를 요청했다.
  2. WAS는 쓰레드 풀에서 쓰레드를 하나 조회한다.
  3. thread-A가 할당되었다.
  4. thread-A는 사용자A의 데이터를 쓰레드 로컬에 저장한다.
  5. 쓰레드 로컬의 thread-A 전용 보관소에 사용자 A 데이터를 보관한다.

응답

  1. 사용자 A의 HTTP 응답이 끝난다.
  2. WAS는 사용이 끝난 thread-A를 쓰레드 풀에 반환한다. 쓰레드를 생성하는 비용은 비싸기 때문에 쓰레드를 제거하지 않고, 보통 쓰레드 풀을 통해서 쓰레드를 재사용한다.
  3. thread-A는 쓰레드 풀에 아직 살아있다. 따라서 쓰레드 로컬의 thread-A 전용 보관소에 사용자 A의 데이터도 함께 살아있게 된다.

요청

  1. 사용자 B가 조회를 위한 새로운 HTTP 요청을 한다.
  2. WAS는 쓰레드 풀에서 쓰레드를 하나 조회한다.
  3. 쓰레드 thread-A가 할당되었다.(물론 다른 쓰레드가 할당될 수도 있다.)
  4. 이번에는 조회하는 요청이다. thread-A는 쓰레드 로컬에서 데이터를 조회한다.
  5. 쓰레드 로컬은 thread-A 전용 보관소에 있는 사용자 A 값을 반환한다.
  6. 결과적으로 사용자 A 값이 반환된다.
  7. 사용자 B는 사용자 A의 정보를 조회하게 된다.

결론

위와 같은 과정 속에서 생기는 문제를 예방하려면 특정 요청이 종료되었을 때 쓰레드 로컬의 값을

ThreadLocal.remove();

를 통해서 반드시 제거해줘야 한다.

참고: 김영한의 스프링 핵심원리 고급편

profile
주니어 백엔드 개발자

0개의 댓글