≣ 목차
스프링으로 개발을 하다가 보면 예상하지 못하는 동시성 문제가 발생할 수 있습니다. 스프링에서 스프링 빈은 기본적으로 싱글톤으로 등록됩니다. 이는 애플리케이션 컨텍스트 내에서 해당 빈의 인스턴스가 하나만 생성되고, 모든 요청이 한 개의 인스턴스를 공유하게 되어서 예상 못하는 동시성 문제가 발생할 수 있습니다.
동시성 문제란?
동시성 문제는 여러 사용자가 동시에 같은 요청을 할 때 발생하는 문제로, 여러 스레드가 동시에 동일한 로직을 호출하게 되어 데이터의 일관성이 깨지거나 예기치 않은 결과가 발생하는 상황을 말합니다.
동시성 문제의 원인
다중 사용자 이용: 여러 사용자가 동시에 시스템에 접근하여 동일한 자원에 대한 요청을 보낼 때
스레드의 비동기 처리: 비동기적으로 실행되는 스레드들이 동일한 데이터에 접근할 경우
공유 자원: 여러 스레드가 공유하는 자원에 대한 동시 접근
쓰레드 로컬(Thread Local)이란?
쓰레드 로컬(Thread Local)은 Java에서 제공하는 기능으로, 각 쓰레드가 독립적으로 사용할 수 있는 내부 저장소를 제공합니다. 즉 쓰레드의 전용 보관소가 생겨 동시성 문제를 해결할 수 있습니다.
쓰레드 로컬 주요 메소드
값 저장: ThreadLocal.set(xxx)
값 조회: ThreadLocal.get()
값 제거: ThreadLocal.remove()
public class ThreadLocalExample {
// ThreadLocal 변수를 선언
private static ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();
public static void main(String[] args) {
// 쓰레드 1 생성
Thread thread1 = new Thread(() -> {
// 쓰레드 1에서 쓰레드 로컬 변수에 값 설정
threadLocalValue.set(1);
System.out.println("Thread 1: " + threadLocalValue.get());
});
// 쓰레드 2 생성
Thread thread2 = new Thread(() -> {
// 쓰레드 2에서 쓰레드 로컬 변수에 값 설정
threadLocalValue.set(2);
System.out.println("Thread 2: " + threadLocalValue.get());
});
// 쓰레드 시작
thread1.start();
thread2.start();
// 쓰레드가 종료될 때까지 대기
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 쓰레드 로컬 변수의 값 제거
threadLocalValue.remove();
}
}
쓰레드 로컬 주의사항
ThreadLocal을 사용할 때 반드시 인지해야할 주의할 점이 있습니다. ThreadLocal을 사용할 때 사용 후에 비워주지 않는다면 해당 Thread를 부여받게 되는 다른 사용자가 기존에 세팅된 ThreadLocal의 데이터를 그대로 사용할 수도 있습니다. 그렇기에, Thread의 사용이 끝나는 시점에 Thread Pool에 반환을 하기 직전 반드시 ThreadLocal을 초기화시켜주는 작업을 해줘야 합니다.
참고자료
스프링 핵심 원리 - 고급편(김영한)
'JAVA > JAVA' 카테고리의 다른 글
전략(Strategy) 패턴 정리 (1) | 2024.09.11 |
---|---|
템플릿 메소드(Template Method) 패턴 정리 (4) | 2024.09.10 |
[JAVA]체크 예외와 언체크 예외 (1) | 2024.08.12 |
[JAVA+DB] DataSource 진짜 간단 정리 (0) | 2024.08.05 |
[Java] NumberFormat클래스 정리 (0) | 2024.07.12 |