24
Design Patterns Study 3. Singleton pattern

Design patterns 스터디 - Singleton 패턴

Embed Size (px)

Citation preview

Page 1: Design patterns 스터디 - Singleton 패턴

Design Patterns Study3. Singleton pattern

Page 2: Design patterns 스터디 - Singleton 패턴

본 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기 조현호 서울시립대 이희태

Page 3: Design patterns 스터디 - Singleton 패턴

Singleton pattern란?

클래스의 인스턴스가 오직 1개만 생성되도록 디자인하는 방법에 관한 패턴입니다.

Page 4: Design patterns 스터디 - Singleton 패턴

Q) 잉? 클래스는 붕어빵을 만드는 틀과 같은거 아닌가요? 일단 틀을 만들어 놓고 붕어빵(인스턴스)를

마구 만들고 싶은데!!

한 개만 만들거면 대체 왜 힘들여 클래스를 만든거야!!

Page 5: Design patterns 스터디 - Singleton 패턴

A) 싱글턴 패턴은 굉장히 유용하게 쓰입니다. 생각해봅시다.

만약 컴퓨터의 여러 리소스를 관리하는 객체가 여러개가 생성되면 어떨까요??

a인스턴스와 b인스턴스가 컴퓨터 자원을 활용하는 방법이 서로 다르면 어떻게 될까요??

네, 큰일나죠.. ㅎㅎ 싱글턴 패턴은 특정 클래스가 단 한번만 생성 될 수 있도록 디자인하여 안정성을 높여줄 수 있는 역할을 한답니다.

Page 6: Design patterns 스터디 - Singleton 패턴

그럼 어떻게 객체를 한 번만 생성되게 디자인하죠???

몇 가지를 살펴 봅시다.

Page 7: Design patterns 스터디 - Singleton 패턴

우리는 객체 생성을 위해 new라는 키워드를 사용합니다.

물론 new라는 키워드를 이용해 객체를 생성한다면 여러차례 new를 이용 할 수 있을 것이므로

싱글턴 패턴이 아니겠군요.

흠… 그러면 어떡하면 좋을까요?

Page 8: Design patterns 스터디 - Singleton 패턴

만약 생성자가 private이라면???

Page 9: Design patterns 스터디 - Singleton 패턴

에이… 생성자는 new를 하면 호출이 되는데, 그런 생성자를 private으로 선언하면 객체 생성 자체를 할 수 없잖아요.

Page 10: Design patterns 스터디 - Singleton 패턴

생각을 조금 바꿔보죠.

객체 생성을 꼭 new로 하지 않는다면요?

Page 11: Design patterns 스터디 - Singleton 패턴

느낌 오시나요???

바로 코드 살펴봅시다!

Page 12: Design patterns 스터디 - Singleton 패턴

생성자가 private로 선언되어 new키워드로는 인스턴스를 생성 할 수 없습니다!

static으로 생성할 단 하나의 인스턴스를 담을 변수를 선언합니다.

우리는 new가 아닌 getInstance() 메소드를 이용해 객체를 생성합니다!!! uniqueInstance가 null 경우에만 객체를 생성하고, 그렇지 않으면 이미 생성된 인스턴스를 반환해주는거죠.

Page 13: Design patterns 스터디 - Singleton 패턴

와우~ 신기하죠??

하지만 싱글턴 패턴을 이용하기 위해서는 고민해봐야 할 이슈가 있습니다.

Page 14: Design patterns 스터디 - Singleton 패턴

바로 동기화 이슈입니다.

싱글 쓰레드를 이용할 경우는 상관이 없지만, 만약 멀티 쓰레드를 사용한다고 생각을 해봅시다.

Page 15: Design patterns 스터디 - Singleton 패턴

1번 쓰레드 2번 쓰레드

getInstance(){

getInstance(){

if(uniqueInstance == null){

if(uniqueInstance == null){

uniqueInstance = new Singleton();

uniqueInstance = new Singleton();

return uniqueInstance;

return uniqueInstance;

우리가 JVM이 되었다고 생각해봅시다…

이 시점에서 둘 다 null이므로 인스턴스가 2개 생성되게 됩니다.

Page 16: Design patterns 스터디 - Singleton 패턴

따라서 멀티쓰레드를 이용해 코드를 작성할 때는 싱글턴 패턴에서 심각한 오류가 발생할 수 있으므로

조치를 취해줘야 합니다.

그 방법으로는 가장 간단하게는 synchronized 키워드를 사용해 동기화 해주는겁니다.

이렇게 말이죠.

Page 17: Design patterns 스터디 - Singleton 패턴
Page 18: Design patterns 스터디 - Singleton 패턴

대부분의 자바 어플리케이션은 다중 스레드 환경을 지원하도록 만들어야합니다.

하지만 synchronized 키워드를 이용해 동기화를 하면 굉장히 큰 성능 저하가 생길 수 밖에 없죠.

그럼 어떡하면 좋을까요?

Page 19: Design patterns 스터디 - Singleton 패턴

1. getInstance()의 속도가 그리 중요하지 않다면 그냥 둡니다.

getInstance() 메소드가 별로 어플리케이션에 부담되는 코드가 아니라면 그냥 두는 것도 나쁘지 않습니다.

메소드 동기화를 하면 성능이 거의 100배 정도 저하된다는 것은 기억해둡시다.

하지만 getInstance()가 어플리케이션에서 병목으로 작용한다면 다른 방법을 생각해봐야합니다.

Page 20: Design patterns 스터디 - Singleton 패턴

2. 인스턴스를 처음부터 만들어버립니다.

static으로 선언한 uniqueInstance변수에 new를 이용해 인스턴스를 처음부터 만들어 두는겁니다.

그렇다면 애초에 uniqueInstance == null일 경우가 없으므로 동기화 이슈는 발생하지 않겠죠.

물론 singleton 인스턴스가 몹시 무거워서 필요할 때 생성하는게 더 나을 경우는 좋은 선택이 될 수는 없겠군요.

Page 21: Design patterns 스터디 - Singleton 패턴

3. Double-Checking Locking을 사용합니다.

Double-Checking Locking(DCL)을 사용하면 일단 인스턴스가 생성되어 있는지 확인한 다음,

생성되어 있지 않았을 때만 동기화 할 수 있습니다. 바로 우리가 원하던거죠.

uniqueInstance가 null인 경우만 동기화를 해줍니다!

volatile 키워드를 사용하면 uniqueInstance변수를 동기화 할 수 있습니다. (자바 1.4 이후 부터 사용 가능)

Page 22: Design patterns 스터디 - Singleton 패턴

참고사항

1.2 버전 보다 이전에 나온 JVM의 경우에는 가비지 컬렉터(GC) 버그로 인해

싱글턴 패턴으로 생성된 인스턴스가 다 사용되기도 전에 제거되버리는 경우가 있을 수 있습니다.

이 경우에는 싱글턴 레지스트리를 사용해야 합니다.

Page 23: Design patterns 스터디 - Singleton 패턴

여기까지 해서 클래스 인스턴스가 하나만 만들어지도록 하고, 그 인스턴스에 대한 전역 접근을 제공하는

싱글턴 패턴을 공부해 보았습니다.

어떠셨나요?

Page 24: Design patterns 스터디 - Singleton 패턴

오늘도 수고 많으셨습니다! 간단해 보이지만 고민해야할 점이 좀 있었던

싱글턴 패턴이었습니다. 다음 시간에는 어댑터 패턴을 공부해보도록 합시다!