본문 바로가기

Android/Architecture

[Android] 싱글톤(Singleton) 패턴

728x90

싱글톤 패턴

최초 한번만 메모리를 할당하고 그 메모리에 인스턴스를 만들어 사용하는 디자인 패턴.

싱글톤 패턴을 사용하는 이유

  • 고정된 메모리 영역을 얻어 사용하며, 최초의 한번만 인스턴스를 만들어 사용하기 때문에 메모리 낭비를 방지.
  • Static 으로 인스턴스를 생성하기 때문에 어디에서든 참조할 수 있어 데이터 공유가 편리하다.

싱글톤 패턴의 문제점

  • 싱글톤 인스턴스를 사용하는 다른 객체간의 결합도가 높아져 객체 지향 설계 원칙에 어긋나게 된다.
  • 멀티 쓰레드 환경에서 동기화 처리 등의 문제가 발생할 가능성이 있다.

 

*

멀티 쓰레드 환경에서는 경합 상태가 발생할 수 있다.

경합 상태란 동일한 자원을 2개 이상의 스레드가 동시에 이용하려고 경합하는 상태이다.

이 때, 인스턴스가 1개 이상 생성되는 경우가 발생할 수 있다.

  1. A 스레드가 인스턴스의 존재 여부를 체크한다.
  2. A 스레드가 인스턴스를 생성하기 전에 B 스레드가 인스턴스의 존재 여부를 체크한다.
  3. A 스레드는 체크 결과 인스턴스가 존재하지 않음을 확인하여 인스턴스를 생성한다.
  4. B 스레드 또한 존재하지 않음을 확인하여 인스턴스를 생성한다.
  5. 2개의 인스턴스가 생성된다.

위와 같은 경우는 간단한 예제를 통해 확인할 수 있다.

 

...

private static sampleSingle single = null;

public static sampleSingle getSingle() {
	if (single == null) {
		single = new sampleSingle();
	}
    
    return single;
}

...

 

A 스레드가 if문을 통해 인스턴스를 확인하고 new 를 통해 새로운 인스턴스를 만들게 되는데,

인스턴스를 만들기 전에 B 스레드가 if문을 통해 조건을 확인하게 된다면 이 타이밍에는 single 인스턴스가 존재하지 않기 때문에 B 스레드 또한 해당 조건이 true로 나오기 때문에 새로운 인스턴스를 생성하게 되는 것이다.

 

 

위의 문제는 synchronized 를 사용(Lazy initialization)하여 해결이 가능하나, 큰 성능저하가 발생하므로 권장하지 않는다.

 

 

 

정적 클래스

정적(Static) 메서드로만 이루어진 정적 클래스를 사용한다면, 싱글턴과 동일한 효과를 얻을 수 있다.

정적 클래스의 특징

  • 인스턴스를 생성하지 않고 메서드의 사용이 가능하다.
  • 정적 메서드를 사용하는 경우, 런타임시에 바인딩 되는 인스턴스 메서드를 사용하는 것 보다 성능면에서 우수하다.
  • 인터페이스를 구현해야 하는 경우라면 사용이 불가능하다.

 

 

728x90