hackerrank.com
Hackerrank.com Practice>Java>Advanced>Java Singleton Pattern
건이두
2019. 12. 2. 13:36
728x90
Singleton Pattern을 이해하고 있는지에 대해서 묻는 문제 입니다.
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
class Singleton{
private Singleton() {}
private volatile static Singleton instance;
public String str;
static Singleton getSingleInstance() {
if(null == instance) {
synchronized(Singleton.class) {
if(null == instance) {
instance = new Singleton();
}
}
}
return instance;
}
}
이렇게 구현하는 것이 가장 일반적입니다.
2가지 동기화 문제를 고려해야 합니다.
- volatile을 사용해서, instance 필드를 항상 메모리로 부터 읽어서, 첫번째 동기화 문제를 해결합니다.
- static 메서드 안에서, Singleton class의 인스턴스를 생성할 때, 동기화 문제를 방지 하기 위해서, Singleton.class로 lock을 걸어 줍니다.
- 만약에, getSingleInstance() 메서드가 static이 아니라면, (즉, 싱글턴 패턴이 아닌 일반 메서드라면) synchronized에 this를 사용할 수 도 있습니다.
holder 클래스를 사용해서 아래와 같이 코딩하는 것도 가능합니다. 하지만, 클래스가 로딩될 때, 인스턴스가 만들어저서, 사용하지 않는 대로, 인스턴스가 계속 만들어져 있는, 단점이 있습니다.
class Singleton{
public String str;
private Singleton() {}
private class MyHolder {
static Singleton instance = new Singleton();
}
static Singleton getSingleInstance() {
return MyHolder.instance;
}
}
아래와 같이 class level lock을 사용하지 않으면, 멀티 쓰레드 환경에서 호출 될 경우, 여러개의 인스턴스가 만들어질 수 도 있습니다. statick 메서드 이기 때문에, object level lock이 아닌 class level lock을 사용합니다.
class Singleton{
private Singleton() {}
private volatile static Singleton instance;
public String str;
static Singleton getSingleInstance() {
if(null == instance) {
instance = new Singleton();
}
return instance;
}
}
Object level lock vs Class level lock in Java 에 대한 보다 깊은 내용은 아래 글을 참고하세요.
https://howtodoinjava.com/java/multi-threading/object-vs-class-level-locking/
728x90