이전 포스팅에서 Thread 사용법에 대해서 다룬적이 있다.
자세한 내용은 아래 참고 포스팅 참고 바란다.
하지만 대량 트래픽이 존재하는 서비스에서 매번 발생하는 문제.
바로 동시성 이슈 이다.
자바 Spring에서는 기본으로 Bean을 singleton으로 띄우게 된다.
singleton 에 대한 자세한 내용은 아래 참고 포스팅 참고 바란다.
테스트를 할 경우에는 하나의 요청이 들어오니 상관이 없지만
동시에 여러 요청이 들어올 경우에 하나의 bean에 여러 값을 동시에 입력을 하면 출력은 다른 값이 나오는 이슈가 생길수 있다.
아래 그림을 보면
하나의 클라이언트가 하나의 bean에 입력을 하면 정상적으로 입력한 값이 bean에 저장되고 그 값을 가져올수 있다.
하지만 아래 그림과 상황이 같다면
프로세스 순서는 앞에 숫자대로 붙어있다.
1. 클라이언트 1이 먼저 bean에 hello라는 값을 입력한다. 그러면 bean은 hello값을 저장해둔다.
2. 클라이언트 2가 다음으로 bye 라는 값을 bean에 입력한다. 그러면 bean은 bye 값을 저장한다.
3. 클라이언트 1이 1번단계에서 저장한 값을 가져오려고 한다. 그럼 bean에서 값을 가져오는데 bye가 가져오게 된다.
4. 클라이언트 2는 자신이 저장한 값을 가져오지만 클라이언트 1이 요청을 했는지 조차 알수 없고 클라이언트2 역시 또다른 클라이언트가 저장을 하면 자신의 값을 못 가져온다.
이럴경우에 thread는 독립된 자신만의 공간이 필요하다.
이때 사용되는게 ThreadLocal 이다.
사용은 dto 처럼 set으로 설정하고 get으로 가져온다.
그리고 중요한 것은 사용이 완료되고 클라이언트의 요청이 끝난다면 직접 remove를 호출하여 값을 비우게 해야한다.
GC 에서 값을 지우는것과 별개로 ThreadLocal은 값을 remove하지 않는다면 다른 클라이언트가 저장되어있는 값을 사용할수가 있기 때문이다.
사용법은 아래와 같다.
//선언 public static ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>(); // ThreadLocal //값 저장 threadLocalValue.set(1); //값 가져오기 threadLocalValue.get(); //값 지우기 threadLocalValue.remove(); |
참고 포스팅
https://thenicesj.tistory.com/715
https://thenicesj.tistory.com/640
'IT > Java' 카테고리의 다른 글
no main manifest attribute, in Project-version.jar (52) | 2023.10.17 |
---|---|
CountDownLatch (다른 쓰레드 대기) (61) | 2023.10.13 |
try-catch 예외처리 비용 (47) | 2023.10.11 |
Java에서 Thread (Runnable) (60) | 2023.10.10 |
[Eclipse] method 생성 시 자동 생성되는 주석 제거 방법 (62) | 2023.10.09 |
댓글