싱글톤 패턴

개발하다 보면 싱글톤 이라는 말을 종종 듣곤한다.
싱글톤 패턴이란, 클래스의 객체는 오직 하나만 만들어지고 어디서든 그 객체에 접근할 수 있어야 한다.

아래 코드는 싱글톤의 예이다. 주목할 부분은 생성자인데, private로 선언했기 때문에 singeton class 내부에서만 인스턴스를 생성할 수 있다. 인스턴스를 생성하는 주체는 오직 자기 자신이며, 한번 만들어지면 if문에 따라 존재하는 인스턴스를 반환하기 때문에 두번 이상 생성될 수 없다. 또한 public getInstance 메소드를 통해 어디서든 singleton 인스턴스를 받을 수 있다.

public class singleton {
 private static singleton only_one_instance;
 
 private singleton() {}
 
 public static singleton getInstance() {
  if(only_one_instance == null) {
   only_one_instance = new singleton();
  }
  return only_one_instance;
 }
}
멀티 스레드 환경에서 싱글톤 객체의 생성은 종종 문제를 일으킨다.
스레드 A,B가 있다고 할때 위 코드를 실행하는 순서가 아래와 같은 흐름을 탄다고 하자.

1. 스레드 A가 if(only_one_instance == null) { 구문을 수행하였다.
2. 스레드 B가 cpu time을 얻어 f(only_one_instance == null) { 구문을 수행하였다.
3. 스레드 B가 only_one_instance = new singleton(); 구문을 수행하여 instance를 생성했다. 4. 스레드 A가 cpu time을 얻어 only_one_instance = new singleton(); 구문을 수행하여 instance를 생성했다. 

위와 같은 흐름으로 수행되면 인스턴스가 2개가 생성되어 예상치 못한 결과를 얻을 수 있다. 책에서는 위 현상을 막기 위해 3가지 정도의 방법을 제안했다.

1. if문으로 인스턴스를 체크하여 생성하는 로직에 lock을 걸어 스레드를 동기화 하는 방법
2. 내부 클래스 인스턴스 (only_one_instance)를 선언과 동시에 초기화하는 방법
3. volatile 키워드를 사용하여 멀티스레딩 환경에서도 안전하게 사용하는 방법
 - private volatile static singleton only_one_instance;

댓글 없음:

댓글 쓰기