반응형
Kotlin에서 이런 개념을 쓰고 싶으면 Objeect를 쓰면 된다. 동기화 문제도 저절로 처리.
그래서 코틀린 코드로는 이짓을 해볼 의미가 없다.
자바에서는 직접 구현해주어야 한다.
1. 기본형
public class TestSingleton {
private static TestSingleton testSingletonObj;
private TestSingleton(){}
public static TestSingleton getTestSingletonObj() {
if(testSingletonObj == null){
testSingletonObj = new TestSingleton();
}
return testSingletonObj;
}
}
멀티 Thread환경에서 동기화문제가 있다.
2. getTestSingletonObj에 Synchronized추가
public class TestSingleton {
private static TestSingleton testSingletonObj;
private TestSingleton(){}
public static synchronized TestSingleton getTestSingletonObj() {
if(testSingletonObj == null){
testSingletonObj = new TestSingleton();
}
return testSingletonObj;
}
}
synchronized하면 동기화 문제는 없어지지만 100배정도 느려진다.
3. DCL(Double Check Locking)
public class TestSingleton {
private static volatile TestSingleton testSingletonObj;
private TestSingleton(){}
public static TestSingleton getTestSingletonObj() {
if(testSingletonObj == null){
synchronized (TestSingleton.class){
if(testSingletonObj == null){
testSingletonObj = new TestSingleton();
}
}
}
return testSingletonObj;
}
}
한번 if문으로 존재여부를 확인하고, 다시 체크하면서 synchronized를 처리한다. 처음 생성 이후에는 syncrhonized를 하지 않기 때문에 성능이 좀 더 낫다.
*volatile
volatile은 컴파일러에게 해당하는 변수에 대한
최적화(Optimize)를 하지
않게 하는 키워드입니다.
volatile이 선언되어있지 않은 변수는 값이 변경되면
register에 cache된 상태에서
실질적인 메모리로의 반영이 되지 않는 경우가
있습니다.
단일 쓰레드의 프로그램이라면 별 상관 없겠지만,
다중쓰레드 프로그램일때, 여러 쓰레드가 한 변수에
접근한다면,
문제가 발생 할 수 있겠죠.
최적화(Optimize)를 하지
않게 하는 키워드입니다.
volatile이 선언되어있지 않은 변수는 값이 변경되면
register에 cache된 상태에서
실질적인 메모리로의 반영이 되지 않는 경우가
있습니다.
단일 쓰레드의 프로그램이라면 별 상관 없겠지만,
다중쓰레드 프로그램일때, 여러 쓰레드가 한 변수에
접근한다면,
문제가 발생 할 수 있겠죠.
*volatile & synchronized
synchronized는 코드 블록을 한 번에 한 쓰레드만 실행하도록 제한합니다.
volatile은 변수를 접근할 때 캐시를 사용하지 않고 무조건 메모리에서 읽어오도록 합니다.
값이 여기저기서 바뀌다 보면 쓰레드마다 캐시 내용이 달라서 불일치가 생길 수도 있거든요.
4. 중첩클래스(Nested Class)를 활용한 Holder
public class TestSingleton {
private TestSingleton(){}
private static class SingletonHolder{
public static final TestSingleton INSTANCE = new TestSingleton();
}
public static TestSingleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
getInstacne 매소드가 호출되고 난 후에만
SingletonHolder가 참조되고 Singleton객체가 생성된다.
LazyInitialization기법을 사용하여 메모리점유면에서 유리.
Synchronized 안써서 성능 좋음.
두개의 Thread가 동시에 getInstacne접근해서 뭔가 문제가 생길 것 같지만
최신 JVM은 클래스를 초기화하기 위한 필드 접근을 동기화한다.
JVM에 짬때기는 기법.
일단 초기화 되면 이후 getInstacne매소드가 호출되어도 new TestSingleton은 호출되지 않는다
반응형
'Android > Desgin Pattern' 카테고리의 다른 글
MVC, MVP, MVVM 비교 (0) | 2019.05.10 |
---|---|
MVP패턴 (+BaseActivity, BasePresenter, BaseView) (0) | 2019.05.07 |
Listener (0) | 2019.03.21 |
Callback(Listener) 예제 (0) | 2018.12.11 |
[kotlin] MVP패턴 (0) | 2018.12.10 |