본문 바로가기

Spring

Spring의 싱글톤 빈이 무상태여야 하는 이유

Spring의 싱글톤 빈이 무상태여야 하는 이유

자바의 메모리 구조

Method Area, Heap, Stack, PC Register, Native Method Stack이 있다

 

Method Area는 C에서의 코드(텍스트) 영역과 데이터 영역이 합쳐진 느낌?(내 생각)

클래서 정보, 전역 변수, static 변수의 정보가 저장된다

모든 스레드에 정보가 공유된다.

 

Heap은 런타임 중 동적으로 할당되는 부분이며

가비지 컬렉터가 여기에 있는 사용하지 않는 값을 제거한다.

모든 스레드에 정보가 공유된다.

 

Stack에는 지역변수가 저장된다.

스레드마다 각각 존재하기 때문에 스레드에 정보가 공유되지 않는다.

스프링으로 여러 요청이 동시에 들어오면?

톰캣은 스레드풀을 미리 만들어놓는다
그리고 요청이 들어올 때 스레드를 하나씩 할당한다.

스프링에서 빈은 힙에 저장된다.

자 그럼 빈은 모든 스레드가 공유한다.

유상태 싱글톤 빈

@Service
public class StudentService {
	private String studentName = ""; // 상태
	...
}

StudentService의 studentName은 method area에 저장되므로 모든 스레드에 정보가 공유된다.

스레드 A의 요청에 따라 studentName을 "aaa"라고 저장했다.

그런데 동시에 들어온 스레드 B의 요청에 따라 studentName을 "bbb"라고 저장했다.

스레드 A의 응답이 나가기 전에 스레드 B의 요청에 따라 studentName은 "bbb"가 되었고,

스레드 A의 응답으로 "bbb"가 반환되었다.

!!! 뭔가 잘못되었다!

이것이 유상태 싱글톤 빈의 문제점이다.

무상태 싱글톤 빈

@Service
public class StudentService {
    public String getStudentName() {
        String studentName = "";
        studentName = ... // repository에서 가져오는 등의 작업 후 student에 저장
        return studentName;
    }
}

여기에서의 studentName은 스택에 저장된다.

스택은 스레드마다 각각 존재하기 때문에 정보가 공유되지 않는다.

여기에서의 studentName은 공유되지 않으므로

스레드마다 각 요청에 대해서 다른 스레드의 영향을 받지 않고 의도한 대로 응답을 반환할 수 있다.

참고

https://velog.io/@shin_stealer/자바의-메모리-구조

https://leezzangmin.tistory.com/41

 

너무 후루룩 썼나