스레드 단위로 로컬 변수를 제공하는 클래스
get
또는 set
메서드를 통해 접근하는 각 스레드가 고유하고 독립적으로 초기화 된 변수의 복사본을 갖는다는 점에서 일반 변수와 다름
일반 변수의 수명은 특정 코드 블록 범위 내에서만 유효
stack 영역에 변수를 선언하는 것에 대한 단점 해소 가능
영역 | 설명 |
---|---|
Heap | 일반적으로 모든 thread에서 접근 가능 |
stack | thread 하나당 생성되는 메모리 영역이므로 thread간 접근 불가능 • 변수 공유 : 파라미터로 받아 사용 • 변수 사용 : 다른 곳에서 사용하려면 리턴값으로 제공 |
ThreadLocal 인스턴스는 일반적으로 상태를 스레드와 연결하려는 클래스의 private static 필드
→ 다른 스레드에서 해당 값을 접근하거나 변경하지 않는 것을 보장
ex) 사용자 ID 또는 트랜잭션 ID
내부적으로 thread 정보를 key로 하여 값을 저장해두는 Map 구조를 가지고 있음
ThreadLocal.set()
으로 현재 스레드의 로컬 변수에 값 저장ThreadLocal.get()
으로 현재 스레드의 로컬 변수 값 조회ThreadLocal.remove()
로 현재 스레드의 로컬 변수 값 삭제//객체 생성
ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();
//스레드의 로컬 변수에 값 저장
threadLocalValue.set(1);
//스레드의 로컬 변수 값 조회
Integer result = threadLocalValue.get();
//스레드의 로컬 변수 값 삭제
threadLocal.remove();
public class ThreadLocalExample {
public static void main(String[] args) {
MyRunnable sharedRunnableInstance = new MyRunnable();
Thread thread1 = new Thread(sharedRunnableInstance);
Thread thread2 = new Thread(sharedRunnableInstance);
thread1.start();
thread2.start();
thread1.join(); //wait for thread 1 to terminate
thread2.join(); //wait for thread 2 to terminate
}
}
public class MyRunnable implements Runnable {
private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
@Override
public void run() {
threadLocal.set( (int) (Math.random() * 100D) );
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println(threadLocal.get());
}
ThreadLocal은 한 스레드에서 실행되는 코드가 동일한 객체를 사용할 수 있도록 해줌
→ 스레드와 관련된 코드에서 파라미터를 사용하지 않고 객체를 전파하기 위한 용도로 주로 사용
- 사용자 인증정보 전파 : Spring Security에서 사용자 인증 정보를 전파하기 위해 사용
- 트랜잭션 컨텍스트 전파 : 트랜잭션 매니저가 트랜잭션 컨텍스트 전파를 위해 사용
- 스레드에 안전해야 하는 데이터 보관
스레드 기준으로 동작해야 하는 기능을 구현할 때
📖 참고