본문 바로가기
IT/Java

ThreadLocal (동시성문제) 사용법 및 주의사항

by 성준하이 2023. 10. 12.
반응형

이전 포스팅에서 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

 

Java에서 Thread (Runnable)

이전 포스팅에서 Thread 에 대해 다룬적이 있다. 자세한 내용은 참고 포스팅 참고 바란다. Java에서 Thread란 참고포스팅의 Thread와 비슷한 개념으로 실행하는 주체를 말한다. 코드가 돌아가기 위해서

thenicesj.tistory.com

 

https://thenicesj.tistory.com/640

 

Spring 에서 Singleton

singleton 패턴에 대해서는 아래 참고 포스팅을 참고 바란다. spring 에서의 기능중 하나는 의존성 주입인 DI 가 있다. 자세한 내용은 아래 참고 포스팅 참고바란다. 스프링에서는 컨테이너 위에 Bean

thenicesj.tistory.com

 

반응형

댓글