1. 싱글톤 패턴이란
싱글톤 패턴은 클래스가 하나의 인스턴스만 갖도록 보장하고 해당 인스턴스에 대한 전역 액세스 지점을 제공하여 검색할 수 있게 하는 생성 디자인 패턴입니다. 싱글톤 패턴은 리소스를 공유해야 하는 경우나 특정 인스턴스에 대한 액세스를 제어해야 하는 시나리오에서 일반적으로 사용됩니다.
2. 싱글톤 패턴의 특성과 장점
싱글톤 패턴에는 다음과 같은 특성과 장점이 있습니다:
- 클래스가 하나의 인스턴스 객체만 갖도록 보장
- 외부 코드가 인스턴스를 얻을 수 있는 전역 액세스 지점을 제공
- 인스턴스의 반복 생성을 피하며 시스템 리소스를 절약
3. 싱글톤 패턴의 적용 시나리오
싱글톤 패턴은 다음과 같은 적용 시나리오에 적합합니다:
- 로거: 시스템 전체에 하나의 로거만 존재하여 중복 로깅을 방지
- 데이터베이스 연결 풀: 고도로 동시성이 높은 환경에서는 싱글톤 패턴을 사용하여 데이터베이스 연결의 빈번한 생성과 소멸을 피할 수 있음
4. Golang에서의 싱글톤 패턴 구현
Golang에서는 싱글톤 패턴을 구현하는 다양한 방법이 있습니다. 아래는 두 가지 일반적인 구현 방법입니다.
4.1. 게으른 초기화 및 즉시 초기화를 사용한 구현
게으른 초기화는 처음 사용할 때 인스턴스 객체를 생성하고, 즉시 초기화는 프로그램 시작 시에 인스턴스 객체를 생성합니다.
// 게으른 초기화 싱글톤 패턴 구현
package singleton
type Singleton struct {
}
var instance *Singleton
func GetInstance() *Singleton {
if instance == nil {
instance = &Singleton{}
}
return instance
}
// 즉시 초기화 싱글톤 패턴 구현
package singleton
type Singleton struct {
}
var instance *Singleton = &Singleton{}
func GetInstance() *Singleton {
return instance
}
4.2. 싱글톤 패턴의 스레드 안전성 문제
위의 게으른 초기화 구현 방법은 다중 스레드 환경에서 문제가 발생할 수 있습니다. 여러 스레드가 동시에 if instance == nil
조건에 들어가면 여러 인스턴스가 생성될 수 있습니다.
4.3. sync.Once를 사용한 스레드 안전한 싱글톤 패턴 구현
sync.Once
를 사용하면 초기화 코드를 실행하는 고루틴이 하나뿐임을 보장하여 스레드 안정성 문제를 해결할 수 있습니다.
// sync.Once를 사용한 스레드 안전한 싱글톤 패턴 구현
package singleton
import (
"sync"
)
type Singleton struct {
}
var instance *Singleton
var once sync.Once
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})
return instance
}
4.4. sync.Mutex를 사용한 스레드 안전한 게으른 초기화 싱글톤 패턴 구현
스레드 안전한 게으른 초기화 싱글톤 패턴의 또 다른 구현 방법은 sync.Mutex
를 사용하여 락을 걸고 단 하나의 고루틴만 초기화 작업을 실행하도록 보장하는 것입니다.
// sync.Mutex를 사용한 스레드 안전한 게으른 초기화 싱글톤 패턴 구현
package singleton
import (
"sync"
)
type Singleton struct {
}
var instance *Singleton
var mu sync.Mutex
func GetInstance() *Singleton {
if instance == nil {
mu.Lock()
defer mu.Unlock()
if instance == nil {
instance = &Singleton{}
}
}
return instance
}