소프트웨어 디자인 패턴 중 하나로, 특정 클래스의 인스턴스가 오직 하나만 생성되도록 보장하는 패턴.
전역적으로 접근 가능한 유일한 객체를 제공하며, 주로 설정 클래스나 로깅 클래스 등에서 사용된다.
주요 목적
시스템 내에서 해당 클래스의 인스턴스가 한 번만 생성되고, 동일한 인스턴스가 여러 곳에서 사용될 수 있도록 하는 것
싱글턴 패턴의 주요 특징
1. 유일한 인스턴스 보장
클래스의 인스턴스가 하나만 존재하도록 보장한다.
2. 전역 접근
생성된 인스턴스에 전역적으로 접근할 수 있도록 한다.
3. 메모리 절약
하나의 인스턴스만 생성되기 때문에 메모리 낭비를 줄일 수 있다.
4. 인스턴스 수명 관리
인스턴스가 언제 생성되고, 파괴될지 제어 할 수 있다.
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
# 사용 예시
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # 출력 : True
싱글턴 패턴을 사용할 때 주의할 점은 멀티스레드 환경에서의 안전성입니다. 멀티스레드 환경에서 싱글턴 패턴을 구현할 때는 동기화(synchronization)를 통해 인스턴스가 한 번만 생성되도록 보장해야 합니다.
Spring 프레임 워크에서 Bean
스프링 프레임워크에서 빈은 기본적으로 싱글톤 스코프로 관리된다.
별도로 스코프를 지정하지 않으면, Spring 컨테이너는 각 빈 클래스에 대해 하나의 인스턴스만 생성하고, 이를 애플리케이션 전역에서 재사용한다.
싱글턴 패턴을 사용하는 이유
DI(Dependency Injection 의존성 주입) 컨테이너는 요청이 많은 트래픽 사이트에서 계속 객체를 생성하게 되면 메모리 낭비가 심하다. 싱글턴 패턴을 통해 동일한 객체를 재사용함으로써 메모리 사용을 최적화하고 성능을 향상시킬 수 있다.
싱글턴 패턴은 객체 인스턴스를 공유하기 때문에 객체 상태가 있도록 (stateful) 하게 설계하면 안된다.
동기화 문제
멀티쓰레드 환경이라면 싱글통 객체가 여러 쓰레드에 의해서 동시에 접근되는 경우가 발생하고 공유 자원에 대한 경쟁 상태가 발생할 수 있다.
예시 코드 (출처 : https://kangworld.tistory.com/326 )
@Component
public class SessionStore {
// key : userId
// value : session string
private final HashMap<Long, String> memorySession = new HashMap<>();
// CRUD method ...
}
synchronized 키워드를 통해 특정 메서드나 블록을 동기화 하거나, concurrentHashMap을 사용하여 동기화 문제를 해결할 수 있다.
import org.springframework.stereotype.Component;
import java.util.HashMap;
@Component
public class SessionStore {
// key : userId
// value : session string
private final HashMap<Long, String> memorySession = new HashMap<>();
// 세션 생성
public synchronized void createSession(Long userId, String session) {
memorySession.put(userId, session);
}
// 세션 조회
public synchronized String getSession(Long userId) {
return memorySession.get(userId);
}
// UD...
}
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class SessionStore {
// key : userId
// value : session string
private final ConcurrentHashMap<Long, String> memorySession = new ConcurrentHashMap<>();
// CRUD method ...
}
'Backend · Infra' 카테고리의 다른 글
[ElasticSearch] nested Type (0) | 2024.07.10 |
---|---|
[ElasticSearch] Query (0) | 2024.07.09 |
MSA (Microservice Architecture) (0) | 2024.07.03 |
Node.js 란? (0) | 2024.06.23 |
DB index에 대한 이해 (0) | 2024.06.16 |