개념 정리
ThreadLocal은 각 스레드마다 독립된 변수 값을 가질 수 있게 해주는 클래스다.
공유 변수 없이 스레드 간 간섭 없이 데이터 보관이 가능하다는 게 핵심이다.
즉, 하나의 ThreadLocal 객체를 여러 스레드가 공유해도, 각 스레드마다 별개의 값이 저장된다.
예제 코드로 이해하기
public class ThreadLocalExample {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
Runnable task = () -> {
threadLocal.set((int) (Math.random() * 100)); // 각 스레드 고유 값 저장
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + threadLocal.get());
};
for (int i = 0; i < 5; i++) {
new Thread(task).start();
}
}
}
📌 결과: 각 스레드는 서로 다른 랜덤 숫자를 출력한다.
→ 변수는 공유되지 않으며, threadLocal.get()은 자기 자신만의 값을 리턴한다.
✅ 왜 필요할까?
1. 스레드마다 다른 값을 써야 할 때
예: 로그인한 사용자 정보를 ThreadLocal에 저장하면,
서버에서 동일한 변수를 여러 사용자(스레드)가 쓰더라도 충돌 없이 독립적으로 처리할 수 있다.
public class UserContext {
private static final ThreadLocal<String> currentUser = new ThreadLocal<>();
public static void setUser(String user) {
currentUser.set(user);
}
public static String getUser() {
return currentUser.get();
}
}
→ 필터나 인터셉터에서 사용자 정보를 세팅하고, 서비스 계층에서 자유롭게 사용할 수 있다.
🛑 주의할 점
1. 메모리 누수 위험
ThreadLocal은 참조가 끊기지 않으면 값이 계속 남는다.
→ threadLocal.remove()를 호출해주는 습관이 중요하다.
try {
threadLocal.set("data");
// 작업 수행
} finally {
threadLocal.remove(); // 꼭 해줘야 한다!
}
2. 스레드 풀에서 공유될 경우 문제 발생
스레드 풀을 사용하면 동일한 스레드가 재사용되므로, 이전의 값이 남아있을 수 있다.
→ remove()는 필수다.
ThreadLocal vs synchronized
항목
|
ThreadLocal
|
synchronized
|
데이터 공유
|
스레드마다 독립된 변수
|
여러 스레드가 동일한 변수 공유
|
동기화 필요 여부
|
없음 (스레드마다 따로 보관하므로 안전)
|
필요함 (임계 영역 제어 필수)
|
사용 목적
|
스레드 고유 데이터 저장
|
임계 영역 보호
|
메모리 관리 중요성
|
중요 (remove() 필수)
|
신경 안 써도 됨
|
마무리
- ThreadLocal은 스레드별 상태 관리에 매우 유용한 도구다.
- 스레드 풀을 사용할 경우 remove() 호출 필수다.
- 사용자 정보, 트랜잭션 ID 등 스레드별 상태를 유지해야 할 때 적극적으로 사용할 수 있다.
학스의 개발일지
일상과 코딩 그 사이 어딘가에있는 블로그.. 블로거이자 빅데이터개발자 학스 입니다 JAVA, jQuery, PostgreSQL, MySQL, HIVE, Hadoop 더 많은 정보는 깃허브 주소 https://github.com/hacs2772 를 방문해주세요
hacs2772.tistory.com
'TIPS' 카테고리의 다른 글
CompletableFuture — 자바의 현대적 비동기 프로그래밍 (1) | 2025.06.16 |
---|---|
ReentrantLock vs synchronized — 자바 락의 실전 비교 (2) | 2025.06.02 |
자바에서 volatile, synchronized, AtomicInteger 언제 써야 할까? (0) | 2025.05.26 |
자바에서 불변 객체(Immutable Object)의 중요성과 정의 (0) | 2025.05.19 |
Java에서 ==와 equals()의 차이 완벽 정리 (Heap vs Stack 메모리 차이 포함) (0) | 2025.05.12 |