2. 본 PPT는 Design Patterns Study를 위해 작성되었습니다.
Study에 사용한 교재는 한빛미디어에서 나온
Head First Design Patterns을 사용하였습니다.
예시로 사용된 간단한 코드들은
https://github.com/doubleh777/DesignPatternsStudy.git에서
다운 받으 실 수 있습니다.
Written by NHN NEXT 2기 조현호 For study with NHN NEXT 2기 조현호
서울시립대 이희태
4. Q) 잉? 클래스는 붕어빵을 만드는 틀과 같은거 아닌가요?
일단 틀을 만들어 놓고 붕어빵(인스턴스)를
마구 만들고 싶은데!!
한 개만 만들거면 대체 왜 힘들여 클래스를 만든거야!!
5. A) 싱글턴 패턴은 굉장히 유용하게 쓰입니다.
생각해봅시다.
만약 컴퓨터의 여러 리소스를 관리하는 객체가
여러개가 생성되면 어떨까요??
a인스턴스와 b인스턴스가 컴퓨터 자원을 활용하는 방법이
서로 다르면 어떻게 될까요??
네, 큰일나죠.. ㅎㅎ
싱글턴 패턴은 특정 클래스가 단 한번만 생성 될 수 있도록
디자인하여 안정성을 높여줄 수 있는 역할을 한답니다.
12. 생성자가 private로 선언되어
new키워드로는
인스턴스를 생성 할 수 없습니다!
static으로
생성할 단 하나의
인스턴스를 담을
변수를 선언합니다.
우리는 new가 아닌 getInstance() 메소드를 이용해 객체를 생성합니다!!!
uniqueInstance가 null 경우에만 객체를 생성하고,
그렇지 않으면 이미 생성된 인스턴스를 반환해주는거죠.
14. 바로 동기화 이슈입니다.
싱글 쓰레드를 이용할 경우는 상관이 없지만,
만약 멀티 쓰레드를 사용한다고 생각을 해봅시다.
15. 1번 쓰레드 2번 쓰레드
getInstance(){
getInstance(){
if(uniqueInstance == null){
if(uniqueInstance == null){
uniqueInstance =
new Singleton();
uniqueInstance =
new Singleton();
return uniqueInstance;
return uniqueInstance;
우리가 JVM이 되었다고 생각해봅시다…
이 시점에서 둘 다 null이므로
인스턴스가 2개 생성되게 됩니다.
16. 따라서 멀티쓰레드를 이용해 코드를 작성할 때는
싱글턴 패턴에서 심각한 오류가 발생할 수 있으므로
조치를 취해줘야 합니다.
그 방법으로는 가장 간단하게는
synchronized 키워드를 사용해 동기화 해주는겁니다.
이렇게 말이죠.
18. 대부분의 자바 어플리케이션은
다중 스레드 환경을 지원하도록 만들어야합니다.
하지만 synchronized 키워드를 이용해
동기화를 하면 굉장히 큰 성능 저하가 생길 수 밖에 없죠.
그럼 어떡하면 좋을까요?
19. 1. getInstance()의 속도가 그리 중요하지 않다면 그냥 둡니다.
getInstance() 메소드가 별로 어플리케이션에 부담되는
코드가 아니라면 그냥 두는 것도 나쁘지 않습니다.
메소드 동기화를 하면 성능이 거의 100배 정도 저하된다는 것은
기억해둡시다.
하지만 getInstance()가 어플리케이션에서
병목으로 작용한다면 다른 방법을 생각해봐야합니다.
20. 2. 인스턴스를 처음부터 만들어버립니다.
static으로 선언한 uniqueInstance변수에 new를 이용해
인스턴스를 처음부터 만들어 두는겁니다.
그렇다면 애초에 uniqueInstance == null일 경우가 없으므로
동기화 이슈는 발생하지 않겠죠.
물론 singleton 인스턴스가 몹시 무거워서
필요할 때 생성하는게 더 나을 경우는 좋은 선택이 될 수는 없겠군요.
21. 3. Double-Checking Locking을 사용합니다.
Double-Checking Locking(DCL)을 사용하면
일단 인스턴스가 생성되어 있는지 확인한 다음,
생성되어 있지 않았을 때만 동기화 할 수 있습니다.
바로 우리가 원하던거죠.
uniqueInstance가 null인 경우만
동기화를 해줍니다!
volatile 키워드를 사용하면 uniqueInstance변수를
동기화 할 수 있습니다. (자바 1.4 이후 부터 사용 가능)
22. 참고사항
1.2 버전 보다 이전에 나온 JVM의 경우에는
가비지 컬렉터(GC) 버그로 인해
싱글턴 패턴으로 생성된 인스턴스가
다 사용되기도 전에 제거되버리는 경우가 있을 수 있습니다.
이 경우에는 싱글턴 레지스트리를 사용해야 합니다.
23. 여기까지 해서
클래스 인스턴스가 하나만 만들어지도록 하고,
그 인스턴스에 대한 전역 접근을 제공하는
싱글턴 패턴을 공부해 보았습니다.
어떠셨나요?
24. 오늘도 수고 많으셨습니다!
간단해 보이지만 고민해야할 점이 좀 있었던
싱글턴 패턴이었습니다.
다음 시간에는 어댑터 패턴을 공부해보도록 합시다!