스프링에서 싱글톤 빈을 사용해도 위험하지 않은가?
스프링은 싱글톤 빈인데 어떻게 여러 요청을 한 번에 처리하지?
이런 생각이 든 이유는 10개의 요청이 들어왔다고 할 때 싱글톤 빈들을 공유할텐데 어떻게 같이 사용하지?
요청당 쓰레드가 할당 되는 것은 맞는데 이상한데?? 모르겠다. 그냥 뭔가 이상했다.
이상한 점
- 멀티 쓰레드가 하나의 빈을 사용할 수 있나? 기다려야 하는 것 아닌가?
- 동시에 사용이 가능하다면 값이 변경되면 위험한거 아닌가?
- 어떻게 한개의 빈이 여러 요청을 처리할 수 있는거지?
해당 글을 읽고나니 당연하게 알고 있는 내용이었다. 그래도 정리 해보자.
멀티 쓰레드가 하나의 빈을 사용할 수 있나? 기다려야 하는 것 아닌가?
멀티 쓰레드는 CPU당 하나의 쓰레드를 기본적으로 생성하게 된다.
CPU가 4개이면 8개의 쓰레드를 2개씩 나누어서 한다고 생각하면 된다.
쓰레드가 4개라면 CPU는 각각 일 하기 때문에 기다릴 필요가 없고, 8개 쓰레드라면 컨텍스트 스위칭이 일어나는
찰나의 대기이기 때문에 체감할 수 없다. 그렇기 때문에 멀티 쓰레드가 하나의 객체를 사용하는 것에는 문제가 없다.
이미 알고 있던 내용인데 싱글톤이라는 점에 사로잡혀 착각을 하게 되었다.
동시에 사용이 가능하다면 값이 변경되면 위험한거 아닌가?
이 부분도 알고 있던 부분인데 싱글톤과 멀티 쓰레드를 합쳐서 생각하다 보니 착각하게 된 것 같다.
싱글톤은 기본적으로 상태를 가지면 안된다. 상태를 가지게 되면 해당 질문에 대해 위험한 것이 맞다.
절대로 상태를 가져서는 안된다. 그래서 스프링 빈은 절대 상태를 갖게 설계하지 않는다.
어떻게 한개의 빈이 여러 요청을 처리할 수 있는거지?
결과적으로 이 것 때문에 혼란이 좀 온 것 같다.
만약 메서드를 실행한다고 하면 하나의 객체에 있는 메서드를 여러 쓰레드가 실행한다고? 그게 가능한가?여러 쓰레드가 동시에 객체를 갖고 있는건가?
라고 생각을 했다
중요한 것은 공유이다. 공유를 한다는 것은 단지 로직(코드 = 명령)을 공유하는 것이다. 즉, 각각 객체를 갖는다? 라는 개념이 아니다.
단지 객체에 있는 코드들을 사용하는 것일 뿐이다.
즉, 객체는 힙에 생성이 되고 해당 객체의 정보들은 메서드 영역에 코드들이 존재하는 것이다
.
이 부분이 참 헷갈렸는데 객체는 객체일 뿐 객체에 있는 정보들은 다른 것이다. 객체가 힙에 존재하고 힙을 참조하여,
메서드 영역에 있는 코드를 공유하는 것일 뿐이다. 그렇기 때문에 동시에 사용이 가능한 것이다.
하지만 만약 상태가 존재하는 객체라면 문제가 되는 것이다. 공유한다는 것이 결국 상태도 공유를 하기 때문에
값을 변경하면 모든 쓰레드가 변경된 값을 공유하게 되는 것이다.
결론
공유에 혼동되지 말자. 공유는 단지 공유일 뿐이다.
공유를 한다고 그 객체 자체를 가져가는 것이 아니다. 객체에 있는 정보들을 공유하는 것일 뿐이다.
만약 싱글톤이 아니라면 다른 객체의 정보를 가져다 사용하는 것이고, 그렇기 때문에 상태가 있어도 문제가 되지 않는 것이다.