동시에 접근하는 자원의 타입을 ThreadLocal로 변경하고 기존의 타입을 제네릭 안에 넣는다.
반드시 new ThreadLocal 로 생성 하여 할당한다.
ThreadLocal.set() : 값을 저장
ThreadLocal.get() : 값 조회
ThreadLocal.remove() : 값 제거
쓰레드가 사용이 끝난 후에는 반드시 remove로 값을 제거해야 한다.
🤷 why?
자, 사용자 A가 저장 HTTP 요청을 보낸다고 가장하자 이때 WAS는 쓰레드 풀에서 쓰레드를 꺼내서 Thread-A를 할당한다. 그래서 Thread-A는 사용자 A의 데이터를 Thread-A의 쓰레드 로컬에 저장한다.
그리고 사용자 A의 HTTP 응답이 종료된다. WAS는 사용이 끝난 Thread-A를 쓰레드 풀에 반환한다.
그럼 Thread-A는 쓰레드 풀에 아직 살아있기 때문에 Thread-A의 쓰레드 로컬도 여전히 살아있다.
사용자 B가 조회 HTTP 요청을 보낸다. 이제 WAS는 쓰레드 풀에서 쓰레드를 꺼내서 할당했는데 마침 Thread-A이다. 이때 Thread-A가 조회요청을 수행하면서 이전에 사용자 A가 저장했던 쓰레드 로컬에 있는 데이터를 조회한다. 즉, 사용자 B는 사용자 A의 데이터를 확인하게 되는 심각한 문제가 발생한다.
따라서 해당 쓰레드의 요청이 끝날 때 반드시 쓰레드 로컬 값을 비워줘야 한다.