-
[Java] ThreadLocal 이 필요할 때 (feat. Thread, Thread-Safe, OS, Spring Security)프로그래밍 언어/Java 2022. 3. 15. 13:54
ThreadLocal
오직 한 쓰레드에 의해 읽고 쓰여질 수 있는 쓰레드만의 독립적인 로컬변수
ThreadLocal이 필요할 때
보통 프로세스 내부 자원을 쓰레드들은 공유하게 되는데, 아무처리를 해두지 않으면 쓰레드들은 순서없이 프로세스의 내부자원에 접근하게 된다.
여기서 변경이 생긴다면 그 뒤의 쓰레드들은 변경된 데이터로 작업을 하게 되는데 여기서 생각지 못한 동작을 하게 될 가능성이 많다.
이러한 점을 해결하기 위해 세마포어와 뮤텍스(=이진세마포어)라는 개념이 있지만, 공유변수가 아닌 오직 쓰레드만의 로컬 변수를 사용하고 싶을 때는 ThreadLocal을 사용하게 된다.ThreadLocal의 사용예시 (Spring Security Context Holder)
Spring Security에서 Context Holder를 ThreadLocal로 구현했다.
이는 각 쓰레드들이 각자의 context holder를 가지고 있다는 것이며
그렇기 때문에 무수한 HTTP 요청으로 쓰레드가 여러마리 생기더라도
ContextHolder에서 꺼낸 인증정보들이 꼬이지 않는 것이다.final class ThreadLocalSecurityContextHolderStrategy implements SecurityContextHolderStrategy { private static final ThreadLocal<SecurityContext> contextHolder = new ThreadLocal<>(); public SecurityContext getContext() { SecurityContext ctx = contextHolder.get(); if (ctx == null) { ctx = createEmptyContext(); contextHolder.set(ctx); } return ctx; } public void setContext(SecurityContext context) { Assert.notNull(context, "Only non-null SecurityContext instances are permitted"); contextHolder.set(context); } public SecurityContext createEmptyContext() { return new SecurityContextImpl(); } // 쓰레드풀을 사용하는 환경에서는 이 부분이 매우 중요하다. // 이유는 아래에... public void clearContext() { contextHolder.remove(); } }
ThreadLocal 을 사용할 때 주의점
쓰레드 풀에서 뛰쳐나오는 쓰레드 생성비용이 커서 미리 만들어 둔 쓰레드들이기 때문에 재사용이 이루어진다.
쓰레드풀을 관리하는톰캣(Tomcat)
아저씨를 우리가 사용하는 경우,
톰캣아저씨가 사용하는 쓰레드가 재사용 될 때
이전의 ThreadLocal 변수를 참조하지 않도록 Clear 해주는 작업이 필요하다.
참고로 Spring에는 톰캣이 내장되어 있다.
(즉 Spring 사용시에도 주의해야한다.)톰캣(WAS) 아저씨의 쓰레드풀 관련 글
[Spring/Network] 서블릿과 WAS에 대하여
어떤분께서 "서블릿이 뭔지아세요?" 라고 물어보신적이 있다. 나는 "request랑 response에 접근하게 해주는 객체아니에요?" 라고 답을 했다.. (Spring에서 HttpServlet 객체로 request랑 response랑 접근해서 로
developer-ping9.tistory.com
Thread-Safe
자바에서는 동기화 블록 또는 동기화 메소드를 사용하여 해결한다.
동기화 키워드(Synchronized)를 사용하면
현재 데이터를 사용하고 있는 쓰레드만 자원에 접근하고
다른 쓰레드들은 wait 상태에 빠진다.728x90'프로그래밍 언어 > Java' 카테고리의 다른 글
[Java] JVM 이 무엇인지, 어떻게 작동하는지 대충 훑어보자! (feat. 클래스로더) (1) 2022.05.29 [Java/OS] 세마포어(Semaphore)에 관하여 (2) 2022.03.18 [Java 성능개선] for 루프와 String 연산, 입출력 (0) 2022.01.26 [Java] Swap 함수 구현 (Call-by-value) (0) 2021.10.15 JAVA) 백준으로 공부하는 자바일기 (Dynamic Programming) (0) 2021.10.08