bdfgdfg

생성 패턴 - 싱글톤(Singleton) 본문

웹프로그래밍/Design Pattern

생성 패턴 - 싱글톤(Singleton)

marmelo12 2023. 7. 30. 23:57
반응형

싱글톤 패턴이란

어느 클래스의 인스턴스가 단 하나만 생성되는 패턴을 의미.

 -> 사실 싱글톤은 이게 설명이 전부이지 않을까 생각.

 

싱글톤의 가장 간단한 구현 방식.

class SingleTon
{
    private static SingleTon instance = null;
    
    // 외부에서 생성을 하지못하도록 막아야한다.
    private SingleTon() {}
    
    public static SingleTon getInstance() { 
        if(instance == null)
            instance = new SingleTon();
        return instance; 
    }
}

 

다만 멀티쓰레드 환경을 고려한다면, 싱글톤 객체를 얻어오기 위한 getInstance메소드를 호출할 때, 여러 쓰레드가 동시에 접근하면서 여러개의 싱글톤 객체가 생길 수 있다.

 

좀 더 Thread-Safe한 방법.

 

. getInstance 메소드를 synchronized로 묶는방법.

class SingleTon
{
    private static SingleTon instance = null;
    
    // 외부에서 생성을 하지못하도록 막아야한다.
    private SingleTon() {}
    
    public static synchronized SingleTon getInstance() { 
        if(instance == null)
            instance = new SingleTon();
        return instance; 
    }
}

이 방법도 하나의 해결책이지만, 문제는 싱글톤 객체를 가져올때마다 동기화 메소드이기에 속도저하가 발생한다는 문제.

 

2. 실제 생성부분(임계영역)만 synchronized로

class SingleTon
{
    private static SingleTon instance = null;
    
    // 외부에서 생성을 하지못하도록 막아야한다.
    private SingleTon() {}
    
    public static synchronized SingleTon getInstance() {
    	synchronized(SingleTon.class)
    	{
    		if(instance == null)
    			instance = new SingleTon();
    	}
        return instance; 
    }
}

이것도 해결책이 되지만, 이 또한 메소드 synchronized랑 다를바없이 getInstance를 호출할때마다 lock이 걸리기때문에 속도저하가 발생한다.

 

3. 더블체크 락

class SingleTon
{
    private static SingleTon instance = null;
    
    // 외부에서 생성을 하지못하도록 막아야한다.
    private SingleTon() {}
    
    public static synchronized SingleTon getInstance() {
    	if(instance == null)
    	{
    		synchronized(SingleTon.class)
    		{
    			if(instance == null)
    				instance = new SingleTon();
    		}
    	}
        return instance; 
    }
}

이 방법은 쓰레드가 동시에 접근할 때 우선 instance가 널인지를 체크하고 여러쓰레드가 생성부분에 들어갈때만 락을 거는 방식. 실제로 instance를 생성하기 위해 락 진입점까지 들어간다하더라도, 실제 생성처리를 하는 쓰레드는 단 하나의 쓰레드만이 접근하며, 다른 쓰레드는 생성처리를 완료한 쓰레드가 나올 때 이미 생성된 객체이므로 락 안의 if문에서 걸러지게 된다.

 -> 이 후에는 외부 if문에서 계속 걸러짐.

 

이 방법이 위 방법중에선 제일 좋은방법. 실제로 게임서버 프로그래머로 근무하면서 위와 같은 더블체크 락을 사용했었다.

반응형
Comments