동시성 문제
스프링에서 빈으로 등록된 객체를 여러 쓰레드에서 사용하게되면 이때 사용되는 객체는 싱글톤이므로 여러 쓰레드는 하나의 인스턴스를 사용하게 된다.
만약 인스턴스의 필드 값 변경이 이루어질 경우 여러 스레드는 각각 고유한 필드 값이 아닌 공유된 인스턴스의 필드를 사용하게 되므로 각 스레드에서 기대했던 값을 사용하지 못하게 된다.
* 한 인스턴스의 필드를 조회만 한다면 문제는 발생하지 않고 필드의 값을 변경하게 된다면 동시성 문제가 발생할 확율이 생긴다.
(확율은 트레픽에 비례)
해결 방법
- 스레드 로컬을 사용하면 해당 쓰레드만 접근할 수 있는 특별한 저장소에 접근할 수 있다.
* 자바에서는 쓰레드 로컬을 지원하기 위한 'java.lang.ThreadLocal' 클래스를 제공한다.
필드 타입 스레드 로컬 필드 생성,
var name: ThreadLocal<String?> = ThreadLocal()
- 값 저장 - ThreadLocal.set()
- 값 조회 - ThreadLocal.get()
- 값 제거 - ThreadLocal.remove()
* 주의 사항 - 해당 스레드 로컬을 모두 사용하고 나면 'ThreadLocal.remove()' 를 호출하여 쓰레드 로컬에 저장된 값을 제거해줘야 함. was 환경에서는 스레드를 사용 후 제거하지않고 스레드 풀에 반환하여 재사용하기때문에 remove를 해주지 않으면 이후 요청에서 같은 스레드를 사용할 경우 기존에 남아있던 데이터가 다른 유저에게 노출이 되는 경우가 발생할 수 있다.
'Spring' 카테고리의 다른 글
[Spring] 빈 후처리기 - BeanPostProcessor (0) | 2021.11.08 |
---|---|
[Spring] 프록시 팩토리 (0) | 2021.11.08 |
[Spring] 프록시 패턴 (0) | 2021.11.05 |
[Spring] 전략 패턴 (0) | 2021.11.05 |
[Spring] 템플릿 메서드 패턴 (0) | 2021.11.05 |