1. 싱글톤 패턴

싱글톤 패턴 (Singleton Pattern)은 디자인 패턴 중에 하나로, 클래스의 객체를 한 개만 생성해서 그 객체만을 사용하는 패턴이다.

1-1. 객체를 한 개만 생성하는 이유?

상태값이 없고 기능만을 수행하는 클래스를 사용하려고 여러 곳에서 객체를 생성하면 메모리가 낭비된다. 이런 경우 싱글톤 패턴을 통해 객체를 한 개만 생성하고 이를 돌려쓴다면 메모리적으로 효율이 좋아진다. 자원 낭비 또한 방지할 수 있다.

사용 예시
상태가 없는(Stateless) 클래스, 로깅, 설정 관리, DB 연결 풀

2. 기본적인 싱글톤 패턴의 예시


기존 클래스처럼 생성자로 객체를 만드는 것이 아니라 static 메서드인 getInstance()로 객체를 만든다.

동작 과정

  1. 최초 getInstance() 호출 때는 클래스 변수인 singleton이 null 이니까 객체를 생성하고 이를 반환해준다.
  2. 이후 getInstance() 호출 때는 singleton은 null이 아니니까 만들지 않고 그대로 반환해준다.

3. 싱글톤의 가장 큰 문제

-동시성의 문제

멀티쓰레드 환경에서 우리가 의도한 것고는 다르게 객체가 여러개 생길 수 이싸.

EX) 두 개의 쓰레드가 각자 싱글턴 패턴을 이용한 클래스를 사용하려고 getInstance() 메서드를 호출했다고 가정

1번 쓰레드가 null 확인을 위해 캐시를 확인한다. 확인 후에 객체를 만들려고 시도하려고 한다.

1번이 객체를 다 만들기 전에 2번 쓰레드가 작업을 시작한다. 캐시를 봤는데 Null임을 확인한 2번 쓰레드는 If문 내부를 실행해서 객체를 생성 및 반환한다.

2번 쓰레드의 시간이 끝나고 1번 쓰레드가 작업대에서 못했던 객체 생성 및 반환을 짆ㅇ한다.

싱글톤 패턴에서 의도치 않게 객체가 두 개가 생겨버렸다!!

동시성 문제 발생!!!

4. 멀티쓰레드 환경에서 싱글톤 패턴을 사용하기 위한 방법들의 발전

4-1. getInstance() 때 말고 바로 만들기 (Eager Initialization)


클래스 멤버에 직접 객체를 초기화 해버리는 방법
클래스 로더(Class loader)가 클래스를 로딩할 때 객체를 생성해주게 된다

4-2. Static 블록에 넣기 (Static Block Initialization)


객체 초기화를 직접적으로 하는 것이 아니라 static 블록에 넣는 것
(Static 블록 = 클래스가 최초 로딩되는 1회에만 수행이 되는 블록)
Exception에 대한 처리로직을 구현할 수 있게되어 처리가 가능해짐

4-3. Synchronize를 사용 (Thread safe Lazy initialization)


달라진 점은 getInstance() 메서드에 synchronized라는 키워드가 붙은 것

4-4. 두번 검사 (Double Checked Locking)


Synchronized의 무분별한 사용을 막기 위해 if문이라는 관문을 하나 설치하는 것이다.
이렇게 되면 synchronized의 사용이 줄어들게 되어서 성능 저하를 억제할 수 있게 된다.

4-4-1. 동기화를 다시 한번 막기 (Double Checked Locking + volatile 메서드 사용)


Synchronized의 무분별한 사용을 막기 위해 if문이라는 관문을 하나 설치하는 것이다.
이렇게 되면 synchronized의 사용이 줄어들게 되어서 성능 저하를 억제할 수 있게 된다.

4-5. 클래스 안의 클래스 (Bill Pugh Singleton Implementation a.k.a lazyholder)


Inner class 특징을 활용한 방식
LazyHolder 클래스는 Inner Class라 Singleton클래스가 클래스로더에 의해 로딩이 될 때는 로딩되지 않음
getInstance() 메서드를 호출할 때 로딩이 되고 객체가 생성되게 됨.
멀티쓰레드 환경에서도 안전하고, 사용될 때만 객체가 생성되니 메모리 낭비도 없다

4-6. Enum (Enum Singleton)


Enum 인스턴스는 기본적으로 멀티쓰레드 환경에서 나올 수 있는 문제를 해결해준다.
Enum의 특성을 이용한 방식

profile
slow but steady

0개의 댓글