728x90
- 스레드 로컬은 해당 스레드만 접근할 수 있는 특별한 저장소를 말한다
- 쉽게 이야기해서 물건 보관 창구를 떠올리면 된다. 여러 사람이 같은 물건 보관 창구를 사용하더라도 창구 직원은 사용자를 인식해서 사용자별로 확실하게 물건을 구분해준다.
- 사용자 A, 사용자 B 모두 창구 직원을 통해서 물건을 보관하고, 꺼내지만 창구 지원이 사용자에 따라 보관한 물건을 구분해주는 것이다
일반적인 변수 필드


스레드 로컬



- 자바는 언어 차원에서 스레드 로컬을 지원하기 위한 java.lang.ThreadLocal 클래스를 제공한다.
예제 코드
ThreadLocalService
@Slf4j
public class ThreadLocalService {
private ThreadLocal<String> nameStore = new ThreadLocal<>();
public String logic(String name){
log.info("저장 name={} -> nameStore={}", name, nameStore.get());
nameStore.set(name);
sleep(1000);
log.info("조회 nameStore={}",nameStore.get());
return nameStore.get();
}
private void sleep(int millis) {
try {
Thread.sleep(millis);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
ThreadLocalServiceTest
@Slf4j
public class ThreadLocalServiceTest {
private ThreadLocalService fieldService = new ThreadLocalService();
@Test
public void field(){
log.info("main start");
Runnable userA = () -> {
fieldService.logic("userA");
};
Runnable userB = () -> {
fieldService.logic("userB");
};
Thread threadA = new Thread(userA);
threadA.setName("thread-A");
Thread threadB = new Thread(userB);
threadB.setName("thread-B");
threadA.start();
//sleep(2000); //동시성 문제 발생 X
sleep(100);//동시성 문제 발생
threadB.start();
sleep(3000);//메인 쓰레드 종료 대기
log.info("main exit");
}
private void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
- 해당 쓰레드가 스레드 로컬 값을 다 사용하면 반드시 threadlocal.remove()를 호출해서 스레드 로컬에 저장된 값을 제거해 주어야 한다.
- 각각의 별도 데이터 저장소를 가지면서 동시성 문제가 해결되었다.
728x90
'스프링 핵심 원리(고급편)' 카테고리의 다른 글
| Ch03. 템플릿 메서드 패턴과 콜백 패턴 - 템플릿 메서드 패턴(시작) (0) | 2022.04.09 |
|---|---|
| Ch02. 쓰레드 로컬(ThreadLocal) - 쓰레드 로컬 동기화 (0) | 2022.04.08 |
| Ch02. 쓰레드 로컬(ThreadLocal) - 동시성 문제(예제 코드) (0) | 2022.04.08 |
| Ch02. 쓰레드 로컬(ThreadLocal) - 필드 동기화 (0) | 2022.04.08 |
| Ch01. 예제 만들기 - 로그 추적기(3) (0) | 2022.04.07 |