티스토리 뷰

Spring의 Controller 클래스도 Spring Bean이고 Spring Bean은 기본적으로 싱글톤인데 어떻게 수많은 요청을 Thread-Safe하게 처리가 가능한지 궁금했다.  그런데 이 문제에 대한 답은 JAVA 메모리 구조를 공부했으면 금방 이해할 수 있을 것이다.

@RestController
public class UserController {

    @PostMapping("/users")
    public void save(User user) {
    ...
    }
}

위 코드는 사용자의 정보를 저장하는 Controller의 save 메서드가 있다. 동시에 여러개의 요청이 들어오면 Tomcat은 내부적으로 다음과 같이 요청을 처리한다.

 

  • 요청이 들어온 순서대로 Queue에 담는다.
  • ThreadPool에 현재 가용할 수 있는 Thread가 있는지 체크한다.
    이 체크는 ThreadPool에 있는 Thread가 처리하지않고 별도 Thread가 처리한다.
  • ThreadPool에 가용 Thread가 존재하면 Queue에서 요청을 꺼내어 Thread로 해당요청을 처리한다.
    가용 Thread도 없고 Queue도 꽉 차있을때 요청이 들어오게 되면 RejectedExecutionException이 발생된다.
  • 여러 Thread들이 UserController의 save 메서드를 호출하여 작업을 수행후 Thread를 ThreadPool에 반납한다.
    메서드가 호출되면 메서드 내부에 선언된 매개변수, 지역변수들이 Stack에 쌓이게 되며 해당 메서드가 종료되면 Stack에 쌓였던 변수들이 제거된다. Thread는 각각 Stack 영역을 할당받는데 이 Stack 영역엔 다른 Thread가 접근할 수 없다.

결론

수많은 요청이 오더라도 요청온 순서대로 처리한다. 각 요청마다 Thread를 할당해서 처리하기 때문에 Thread-Safe 하다.


주의할 점

Stack은 Heap영역에 생성된 Object타입의 참조값이 할당되는데 아래처럼 코드를 작성하게 되면 Thread-Safe 하지않게 동작된다.

@RestController
public class UserController {

    @Autowired
    private HttpSession session;

    @PostMapping("/users")
    public void save(User user) {
        session.setAttribute("user", ~~~~);
    }
}

Heap영역에 UserController인스턴스의 참조값이 있는데 만약 여러 Thread에서 인스턴스 변수에 접근해서 값을 조작하는 행위를 하게되면 Multi-Thread에서 의도치 않은 결과가 나타나게 된다.

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함