본문 바로가기

기타/스터디

[스터디1] 싱글턴 패턴과 정적 메소드

싱글턴 패턴

- 목적과 의의

싱글턴 패턴이란 객체의 인스턴스가 오로지 한 개만 생성되도록 설계하는 것입니다.

프로그램 내에서 전역적으로 사용하고 유일해야 하는 경우 사용하는데, 로그 기록, 캐싱, 사용자 설정 등에서 사용됩니다. 

 

- 예제

(1) 순수한 구현

public class Background {
	private static Background instance;
    
    private Background() {
    }
    
    public static Background getInstance(){
    	if(instance == null){
        	instance = new Background();
        }
        return instance;
    }
}

위의 코드를 통해 싱글턴 객체를 생성할 수 있지만, 멀티스레드 환경에서 싱글턴이 보장되지 않는다는 단점이 있습니다.

 

(2) Synchronized 이용

public synchronized static Background getInstance(){}

synchronized 키워드를 통해 하나의 스레드가 접근 중이면 다른 스레드들이 접근하지 못하게 구현할 수 있다.

하지만 getInstance() 메소드를 실행할 때마다 lock이 걸리면서 리소스가 낭비된다는 단점이 있습니다.

 

(3) Double Checked Locking(DCL)

public class Background {
    private static volatile Background instance;
    
    private Background() {
    }
    
    public static Background getInstance(){
    	if(instance == null){
            synchronized (Background.class) {
                if(instance == null){
                    instance = new Background();
                }
            }
        }
        return instance;
    }
}

instance에 volatile 키워드를 붙이면, getInstance() 메소드를 호출할 때 instance가 null인 경우만 synchronized 구문이 실행됩니다.

하지만 JDK 1.5 이상에서만 사용 가능하고, JVM에 대한 이해가 필요하기 때문에 잘 알고 있는 경우만 사용하는 것이 좋습니다.

 

(4) Bill Pugh Solution(Initialization on demand holder idiom) -> 권장되는 방법 중 하나

public class Background {
    private Background(){
    }
    
    private static class BackgroundHolder {
        private static final Background background = new Background();
    }
    
    public static Background getInstance() {
        return BackgroundHolder.background;
    }
}

Background 클래스 안에 static inner class 인스턴스를 생성하여 getInstance() 메소드 호출 시 이 인스턴스를 반환하는 방법입니다.

하지만 사용자가 리플렉션과 직렬화를 통해 임의로 싱글턴을 파괴할 수 있다는 단점이 있습니다.

 

(5) Enum -> 권장되는 방법 중 하나

public enum Background {
    INSTANCE;
}

enum 자체가 싱글턴의 성질을 가지고 있기 때문에 가장 짧고 쉽게 구현할 수 있습니다.

하지만 enum 외의 클래스를 상속할 수 없다는 단점이 존재합니다.

 

- 특징

상속받아서 사용이 가능합니다.

메소드 파라미터로도 사용이 가능합니다.

따라서 완벽한 객체 지향을 필요로 하고 레이지 로딩이 필요할 때 권장됩니다.

 


 

정적 메소드

- 정의

자바에서는 정적 클래스가 따로 없기 때문에 정적 클래스 대신 정적 메소드만을 가지고 있는 클래스를 사용합니다.

정적 메소드는 클래스를 초기화할 때 메소드 영역에 등록되어 프로그램이 끝날 때까지 유지됩니다. 따라서 전역적으로 사용할 수 있고, 유일성을 보장받을 수 있습니다.

 

- 특징

클래스가 아니기 때문에 인스턴스 생성이 불가능하여 클래스 메서드를 이용합니다. 따라서 다형성이나 상속이 필요 없을 때 사용됩니다.

또한 컴파일 시 정적 바인딩이 되기 때문에 싱글턴 패턴보다 성능이 좋습니다.

 

'기타 > 스터디' 카테고리의 다른 글

[스터디1] 자바 스트림  (0) 2022.06.07