일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- jquery
- Random
- while
- 페이징
- 단축키
- 로또
- 25가지 효율적인 sql작성법
- Validations
- 추상클래스
- 자바 야구게임
- 형변환
- 상속
- full text indexing
- 가변인자
- 자바
- 전체텍스트
- Login with OAuth Authentication
- 상속예제
- IBatis procedure
- 전자정부
- 스프링
- 업캐스팅
- 다형성
- 다운캐스팅
- 전체
- 이클립스
- angular2
- Full text
- 야구게임
- Today
- Total
nalaolla
[디자인패턴]싱글턴 패턴(Singleton Pattern) 본문
싱글턴 패턴(Singleton Pattern) = 해당 클래스의 인스턴스가 하나만 만들어지고, 어디서든지 그 인스턴스에 접근할 수 있도록 하기 위한 패턴.
싱글턴 객체는 유일하게 존재 하는 객체입니다. 예를 들면, 레지스트리 설정이라던가, DB 커넥션 객체 등이 여러 개 존재하면 심각한 오류가 발생하거나, 자원이 낭비 될 가능성이 있죠.
(예를 들어서 2개의 설정 객체의 인스턴스를 무작위로 참조 하게 된다면.. )
이런 객체들은 단 하나만 존재하게 해서, 그 객체의 인스턴스만 어디서든 쓸 수 있게 만들어 줘야 합니다.
싱글턴 객체가 이 싱글턴 객체를 어떻게 만들까요?
싱글턴 객체를 만드려면 두 가지의 조건을 만족해야 합니다.
1. 어디서든 접근이 가능하고, 인스턴스를 얻어서 사용할 수 있게 할 것.
2. 객체는 단 하나만이 메모리에 할당 되어 있을 것.
이런 조건들을 살펴 보았을때, 인스턴스를 얻는 getInstance()라는 정적 메소드를 정의 하는 것이 좋아 보입니다. 그래서 이렇게 코드를 작성할 수 있죠.
public class Singleton{
private static Singleton uniqueInstance; // 유일한 변수를 사용하기 위해 정적 변수로 선언
private Singleton() {}
public static Singleton getInstance() {
if(uniqueInstance == null) {
uniqueInstance = new Singleton(); } //필요할때만 객체를 생성하는 방식. 게으른 인스턴스 생성(lazy instantiation)
return uniqueInstance;
}
} |
이렇게 되면 변수와 생성자는 private으로 선언되어 있기 때문에 아무도 건드릴 수 없고, 오직 getInstance() 메소드를 통해 이 객체에 접근할 수 있습니다.
이렇게 작성 된 싱글턴 패턴은 단일 스레드 환경에서는 별 문제가 없지만, 다중 스레드 환경에서는 심각한 문제를 초래할 수 있습니다.
스레드는 프로세스와 같이 스케줄링에 의한 문맥교환(context switching)이 발생합니다. 이렇게 되면 2개의 객체가 생성될 수 있습니다.
이 문제를 해결하려면 세 가지의 방법이 있습니다.
1. synchronized , 동기화를 사용한다.
2. 인스턴스를 필요할 때 생성하지 말고, 아예 처음부터 정적 객체로 생성한다.
3. DCL (Double-Checking Locking)을 사용한다.
1. 동기화를 이용한 방법
public class Singleton{
private static Singleton uniqueInstance; // 유일한 변수를 사용하기 위해 정적 변수로 선언
private Singleton() {}
public static synchronized Singleton getInstance() { // 동기화 처리
if(uniqueInstance == null) {
uniqueInstance = new Singleton(); } //필요할때만 객체를 생성하는 방식. 게으른 인스턴스 생성(lazy instantiation)
return uniqueInstance;
}
} |
--> 이 방법을 사용하면 간단하지만, 객체가 한 번 생성되면 더이상 생성 시킬 필요가 없는데도 불구하고 계속 동기화 처리를 하여 성능 저하가 일어난다는 단점이 있습니다. 약 100배의 속도 저하가 일어납니다.
2. 아예 처음부터 생성하는 방법
public class Singleton{
private static Singleton uniqueInstance = new Singleton(); // 생성과 동시에 초기화
private Singleton() {}
public static Singleton getInstance() {
return uniqueInstance;
}
}
|
--> 이렇게 되면 스레드의 영향을 받지 않고 유일한 객체를 생성할 수 있게 됩니다.
3. DCL 이용하는 방법
public class Singleton {
private volatile Singleton uniqueInstance;
private Singleton() { }
public static Singleton getInstance() {
if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; }
} |
--> 이 방식을 사용하면 synchronized만 사용할때 보다 오버헤드를 매우 낮출 수 있으나 자바 1.4 이하 버전에서는 volatile 예약어를 지원하지 않습니다.
'JAVA > 999. 디자인패턴' 카테고리의 다른 글
[디자인패턴] 어뎁터 패턴 (Adapter Pattern) (0) | 2020.04.09 |
---|---|
[디자인 패턴] 커맨드 패턴 (Command Pattern) (0) | 2020.04.09 |
[디자인패턴] 추상 팩토리 패턴 (Abstract-Factory Pattern) (0) | 2020.04.09 |
[디자인패턴] 팩토리 메소드 패턴 (Factory-Method Pattern) (0) | 2020.04.09 |
[디자인패턴] 데코레이터 패턴 (Decorator Pattern) (0) | 2020.04.09 |