본문 바로가기

cs(with 매일메일)

[260225수] ThreadLocal에 대해 설명해주세요.

Java에서 각 스레드마다 독립적인 변수를 저장할 수 있도록 도와주는 클래스

보통 여러 스레드가 공유 자원을 사용하면 동시성 문제가 발생할 수 있는데, ThreadLocal을 사용하면 스레드별로 데이터를 분리할 수 있어 동기화 없이 안전하게 사용 가능하다. 

각 스레드는 자신만의 ThreadLocalMap을 가지고 있고, ThreadLocal을 키로 사용하여 값을 저장한다. 

하나의 스레드에서 여러 개의 ThreadLocal을 사용할 수 있으며, ThreadLocal은 현재 스레드의 ThreadLocalMap을 제어하는 역할을 한다. 

 

Spring생태계에서는 ThreadLocal을 사용하여

- 트랜잭션 동기화 관리

- 사용자 인증 정보 관리

- 웹 요청의 attribute관리 등의 기능을 제공

 

장점

각 스레드는 ThreadLocal에 접근할 때 다른 스레드와 격리된 값을 가질 수 있다.

그리고 공유 자원이 없기 때문에 synchronized키워드 등을 사용해서 동기화 할 필요가 없다. 

 

주의사항

- 스레드풀을 사용하면 스레드가 재사용된다. 이때 ThreadLocal에 이전 스레드 값이 남아있으면 재사용된 스레드가 올바르지 않은 데이터를 참조할 수 있다. 이를 방지하려면 스레드가 끝난 시점에 remove()메서드를 호출하여 ThreadLocal에 저장된 값을 제거해야한다. 

- 비동기 작업을 수행할 때 ThreadLocal이 예상대로 동작하지 않을 수 있다. 

예를 들어, @Async어노테이션을 사용하면 새로운 스레드에서 비동기 작업이 실행되는데, 비동기 스레드는 기존 스레드에서 ThreadLocal에 저장한 값을 참조할 수 없다. 이 문제는 Spring 4.3이상에서 제공하는 TestDecorator를 사용하여 기존 스레드의 ThreadLocal값을 비동기 스레드에서 복사하는 방식으로 해결 가능하다. 

 

ThreadLocal을 대체하는 방법

- 메서드 인자로 값을 전달

- ConcurrentHashMap같이 thread-safe한 자료구조 사용

- Spring에서는 @requestScope 어노테이션 사용하여 HTTP요청별로 데이터 관리 가능

 

NamedThreadLocal

- Spring에서 제공하는 확장 클래스로, 디버깅을 쉽게하기 위해 이름을 부여할 수 있도록 설계