ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] Singleton Pattern (정리중..)
    Back-End/Spring 2023. 8. 18. 02:07

    싱글톤 패턴

     

    1. 스프링에서는 컨테이너라는 것을 통해서 빈들을 관리한다.

    자바 객체
     :  new 연산자를 사용하여 직접 생성한 인스턴스

    빈 객체
     :  컨테이너에서 관리하는 객체

    싱글톤 패턴의 단점을 보완한 스프링 컨테이너를 통해 빈들을 관리한다.

    싱글톤 패턴을 기반으로 한 만큼 인스턴스가 1개만 생성된다.

    애플리케이션 컨텍스트 내에서 한 번만 생성되고 재사용되어 리소스 낭비를 줄일 수 있다.

     

     

    2. 스프링 컨테이너에서 빈의 생성과 생명 주기를 관리한다.

    객체를 직접 생성하는 대신 스프링 컨테이너에 의존성 주입을 요청하여 필요한 객체를 받아온다.

    스프링 컨테이너가 생성될 때(애플리케이션 실행 시) 빈이 등록되고, 로딩된다.

     

    빈 등록 방법
    • 컴포넌트 어노테이션 사용(@Controller 등)
    • xml, yaml 등
    • Java Config 클래스로 직접 등록

     

     

    3. 멀티 스레드 모델을 사용하며, 스레드 풀을 사용하여 동시에 여러 요청을 처리한다.

    Stateless 로 설계되어 있어서 Thread safe 하다

    Stateless 설계란?

     

     

     

    Q1. 멀티스레드 모델을 사용하여 동시에 여러 요청을 처리한다면, 스프링 빈의 메서드 호출 시 A와 B 요청이 각각 독립적인 스레드에서 처리되지 않나? 그렇다면 빈 내부의 상태 변경은 각 스레드별로 고립되지 않을까?

     

    A1. 아니다. 빈으로 등록하게 되면 인스턴스가 1개밖에 생성되지 않는다.

     

     

     

    Q2. 빈으로 등록된 것을 재활용 한다고 하면 다른 요청에 대해서 데이터가 섞이지 않을까?

     

    A2. Stateless 로 설계되어 있어서 스레드 세이프(Thread Safe) 하다.

     

     Stateless 에 대해서는 앞서 이야기 했다. 상태가 없기 때문에(즉, 데이터를 할당하지 않기 때문에) 공유하는 것은 데이터가 아니라 객체가 된다.

     

     앞서 요청 1개당 스레드 1개가 생성되어 요청을 처리하게 되고, 그것이 멀티스레드 모델이라고 했다. 이 멀티스레드 모델에서 각각의 스레드별로 데이터가 섞이지 않는 것, 이것을 스레드 세이프(Thread Safe) 하다고 표현한다.

     

     

     

    Q3. 요청이 동시에 들어와서 동시성 문제라고 하는 걸까?

     

    A3. 동시에 들어오는 요청을 어떻게 처리할 것인지가 관점이다.

     

     동시에 요청을 받아 처리하더라도 실제로 동작을 할 때에는 순차적으로 처리하는 게 아니라 A요청, B요청, C요청, 다시 A요청 이렇게 번갈아가면서 처리하는 방식으로 진행이 된다. 이것이 동시에 일어난다고 생각하기 쉽지만 사람이 인지하기 힘들 정도로 빠르게 동작하기 그렇게 표현하는 것뿐이다. 번갈아가면서 요청을 처리하는 이 동작을 컨텍스트 스위칭(Context Switching) 이라고 한다. 그래서 이것을 동시성 문제라고 이야기 한다.

     

     

     

    Q4. Stateless 한 클래스만 빈으로 등록하더라도 결국 같은 객체를 사용한다면 영향을 받지 않을까?

     

    A4. 영향을 받지 않으니 Thread Safe 하다고 이야기하는 것이다.

     

     인스턴스 변수와 지역 변수의 차이를 생각해보면 이해가 될 것이다. 공유해서 사용하는 변수는 인수턴스 변수이고, 실질적으로 데이터가 저장되는 변수는 메서드의 지역 변수이기 때문에 호출한 스레드에서만 접근이 가능하다.

     

    빈의 인스턴스 변수

     모든 메서드와 스레드에서 접근이 가능. 동일한 인스턴스가 여러 스레드에서 공유되므로, 이러한 상태를 수정하면 동시성 문제가 발생할 수도 있으므로 stateless 해야 한다.


    메서드의 지역 변수

     메서드 호출시 생성되는 지역 변수는 호출한 스레드에서만 접근 가능. 동시에 여러 스레드에서 해당 메서드를 호출하더라도 각 스레드는 자신만의 지역 변수를 가지기 때문에 동시성 문제가 발생하지 않는다.

     

    @Service
    public class MySingletonService {
    
        private int sharedState;  // 빈의 상태: 여러 스레드에서 공유되는 인스턴스 변수
    
        public void myMethod(int input) {
            int localVar = input;  // 지역 변수: 메서드 호출 시마다 새로 생성되므로 스레드 안전함
    
            // ... ...
        }
    }

     

     

    'Back-End > Spring' 카테고리의 다른 글

    WebClient 와 WebFlux (정리중..)  (4) 2023.06.13
Designed by Tistory.