디자인패턴-싱글톤

김종하·2023년 7월 31일
0

디자인패턴

목록 보기
1/1

싱글톤 패턴?

시스템 내에서 사용 할 인스턴스를 하나만 제공할 수 있도록 하는 생성패턴

왜 필요한가?

시스템 런타임, 환경 세팅에 대한 정보등 인스턴스가 여러개가 있어서는 안되는 경우가 있다.

구현방법

  1. 생성자를 외부에서 사용할 수 없도록 해야한다.
public class Single {
    private Single() {}; // 접근제어자를 통해 외부에서 생성자 접근 못하도록 한다.
}
  1. 외부에서 인스턴스에 접근할 수 있는 메소드를 제공해야한다.
public class Single {

    private Single() {};

// 외부에서 인스턴스에 접근 가능한 메소드 제공
    public static Single getInstance() { 
        return new Single();
    }

}
  1. 외부에서 인스턴스에 접근할 때 동일한 인스턴스를 제공해야한다.
public class Single {
    
    private static Single instance;

    private Single() {};

    public static Single getInstance() {
        if(instance == null) {
            instance = new Single();
        }
        return instance;
    }
}
  1. 멀티쓰레드 환경에서도 안전하게 싱글톤 인스턴스를 제공해야 한다.
    4.1 synchronized 를 활용한다.
public class Single {
    
    private static Single instance;

    private Single() {};

    public static synchronized Single getInstance() {
        if(instance == null) {
            instance = new Single();
        }
        return instance;
    }
}

4.2 클래스 로딩 시점에 인스터를 생성해 사용한다.

public class Single {
    
    private static final Single INSTANCE = new Single();

    private Single() {};

    public static Single getInstance() {
        return INSTANCE;
    }
}

4.3 double checked locking 을 통해 synchronized 비용을 최소화한다.

  • 4.1 에서는 인스턴스 접근시 항상 syncronized 되지만, double checked locking 을 활용하면 인스턴스가 한번 생성된 상태라면 synchronized 처리가 되지 않음으로 성능상 뛰어나다
public class Single {

    private static volatile Single instance;

    private Single() {};

    public static Single getInstance() {
        if(instance == null) {
            synchronized (Settings.class) {
                if(instance == null) {
                    instance = new Single();
                }
            }
        }
        return instance;
    }
}

4.4 static inner 클래스 활용

public class Single {

    private Single() {};
    
    private static class SingleHolder() {
    	private static final Single INSTANCE = new Single();
    }

    public static Single getInstance() {
        return SingleHolder.INSTANCE;
    }
}

싱글톤 패턴 우회

  1. Reflection 을 활용하여 싱글톤 패턴 우회
        Single single = Single.getInstance();

        Constructor<Single> declaredConstructor = Single.class.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        Single reflectedSingle = declaredConstructor.newInstance();

        System.out.println(single == reflectedSingle); // 결과 : false
  1. 인스턴스를 직렬화 후 역직렬화 한다.

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

정보 감사합니다.

답글 달기