Fall in IT.

싱글톤 패턴(Singleton Pattern) 사용하기 본문

프로그래밍언어/Java

싱글톤 패턴(Singleton Pattern) 사용하기

D.Y 2016. 7. 25. 22:49

안녕하세요.


오늘은 싱글톤패턴(Singleton Pattern)에 대해서 알아보고, 간단한 예제에 적용해 보도록 하겠습니다.



싱글톤패턴이란?

  • 싱글톤 패턴을 통해서 하나의 인스턴스만을 생성하고, 사용할 수 있다.
    (하나의 객체만 생성하고 사용해야 할때, 적용할 수 있는 패턴.)

싱글톤패턴 설계
  • 싱글톤 패턴의 기본 설계는 아래와 같습니다.

간단예제) 요구사항
  • 시스템에서 스피커에 접근하는 클래스를 개발한다. 스피커 클래스는 하나만 존재한다.


예제 소스

  • Main 클래스

public class Main {

public static void main(String[] args) {

Speaker speaker1 = Speaker.getInstance();

Speaker speaker2 = Speaker.getInstance();

Speaker speaker3 = Speaker.getInstance();

System.out.println(speaker1);

System.out.println(speaker2);

System.out.println(speaker3);

System.out.println(speaker1.getVolume());

System.out.println(speaker2.getVolume());


speaker1
.setVolume(10);

System.out.println(speaker1.getVolume());

System.out.println(speaker2.getVolume());

System.out.println(speaker3.getVolume());

speaker2.setVolume(20);

System.out.println(speaker1.getVolume());

System.out.println(speaker2.getVolume());

System.out.println(speaker3.getVolume());

}

}

  • Speaker 클래스
    - Speaker클래스의 생성자를 외부에서 호출할 수 없도록 private으로 선언하고, getInstance() 메서드를 사용하여 스피커 인스턴스가 이미 생성되어 있는지를 검사하고 생성되지 않은 상호아이라면 생성자를 호출해 인스턴스를 생성하고, 이미 생성되어 있다면 정적 변수 speaker 변수를 참조하는 인스턴스를 반환합니다.

public class Speaker {


private static Speaker speaker;

private int volume;

private Speaker() {

volume = 5;

}

public static Speaker getInstance()

{

if(speaker == null)

{

speaker = new Speaker();

}

return speaker;

}

public int getVolume() {

return volume;

}

public void setVolume(int volume) {

this.volume = volume;

}

}

  • 실행 결과
    - 모두 같은 객체인 것을 확인 할 수 있습니다. 따라서, 한 객체의 음량을 조절해도 모두 변경됨을 알 수 있습니다.



※ 주의사항

  • 위의 싱글톤패턴 코드를 다중 스레드 어플리케이션에서 사용할 때 문제가 될 수 있습니다.
    (Speaker 클래스에 다중 스레드가 동시에 접근할 때, 인스턴스가 1개 이상 생성될 수 있습니다.)
  • volume 변수에 다중 스레드가 동시에 값을 갱신할 때, volume값이 꼬여(?) 버릴 수 있습니다.


 해결방법
  • 정적 변수에 인스턴스를 만들어 바로 초기화 합니다.
    (정적 변수는 객체가 생성되기 전 클래스가 메모리에 로딩될 때 만들어집니다. 따라서, 초기에 한번 생성된 인스턴스를 반환하게 됩니다.)

    public class Speaker {


    private static Speaker speaker = new Speaker();

    private int volume;

    private Speaker() {

        volume = 5;

    }

    public static Speaker getInstance()

    {

    return this.speaker;

    }

    public int getVolume() {

    return volume;

    }

    public void setVolume(int volume) {

    this.volume = volume;

    }

    }


  • 인스턴스를 만드는 메서드를 synchronized를 사용하여 동기화합니다.

    public class Speaker {


    private static Speaker speaker;

    private int volume;

    private Speaker() {

        volume = 5;

    }

    public synchoronized static Speaker getInstance()

    {

    if(speaker == null)

    {

    speaker = new Speaker();

    }

    return speaker;

    }

    public int getVolume() {

    return volume;

    }

    public synchronized void setVolume(int volume) {

    this.volume = volume;

    }

    }


모두 즐거운 코딩하세요~



Comments