Ch5. 싱글턴 패턴 : 하나뿐인 특별한 객체 만들기
싱글턴패턴은 특정 클래스에 객체 인스턴스가 하나만 만들어지도록 하는 패턴이다.
고전적인 싱글턴 패턴 구현법
위와 같이 인스턴스가 필요한 상황이 닥치기 전까지 인스턴스를 생성하지 않는 방법을 ‘게으른 인스턴스 생성(lazyinstantiation)’ 이라고 한다.
인스턴스가 2개 이상이 되지 않도록 함
레지스트리 설정, 연결 풀, 스레드 풀과 같은 자원풀을 관리하는데 자주 쓰임
생성자가 private
싱글턴 패턴
💡 싱글턴 패턴(Singleton Pattern)은 클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다.
싱글턴 패턴을 실제로 적용할 때는 클래스에서 하나뿐인 인스턴스를 관리하도록 만든다. 그리고 다른 어떤 클래스에서도 자신의 인스턴스를 추가로 만들지 못하게 해야한다.
인스턴스가 필요하다면 반드시 클래스 자신을 거치도록 해야함
어디서든 그 인스턴스에 접근할 수 있도록 전역 접근 지점을 제공한다. 언제든 이 인스턴스가 필요하면 클래스에 요청할 수 있게 만들어놓고, 요청이 들어오면 그 하나뿐인 인스턴스를 건네주도록함.
멀티스레딩 문제 해결하기
2개의 스레드에서 위의 싱글톤 클래스 getInstance()를 실행한다고 가정하면 두개의 다른 인스턴스를 반환할 수 있음.
→ getInstance()를 동기화하면 멀티스레딩과 관련된 문제를 해결 가능.
그러나 속도 이슈가 있을 수 있다. 메소드를 동기화하면 성능이 100배정도 저하됨
→ 인스턴스가 필요할 때는 생성하지 말고 처음부터 만든다.
이런 방법을 사용하면 클래스가 로딩될 때 JVM에서 Singleton의 하나뿐인 인스턴스를 생성해준다.
JVM에서 하나뿐인 인스턴스를 생성하기 전까지 그 어떤 스레드도 uniqueInstance 정적 변수에 접근할 수 없다.
→ DCL을 써서 동기화되는 부분을 줄인다.
DCL (Double-Checked Locking)을 사용하여 인스턴스가 생성되어 있는지 확인한 다음 생성되어 있지 않았을 때만 동기화 할 수 있다.
volatile 키워드를 사용하면 멀티스레딩을 쓰더라도 uniqueInstance 변수가 Singleton 인스턴스로 초기화되는 과정이 올바르게 진행된다.
문제점들
모든 메소드와 변수가 static 으로 선언된 클래스도 유사하지만, 복잡한 초기화가 필요 없는 경우에만 사용 가능
클래스로더마다 서로 다른 네임스페이스를 정의하기에 클래스로더가 2개 이상이면 같은 클래스를 여러번 로딩 가능하므로, 클래스 로더가 여러개라면 싱글턴을 조심해서 사용해야함
리플렉션, 직렬화, 역직렬화도 싱글턴에서 문제가 될 수 있다.
enum 사용하기
위의 문제들을 enum으로 싱글턴을 생성해서 해결할 수 있다.
Last updated