Android/Desgin Pattern

싱글톤(Singleton) 패턴

lipnus 2018. 12. 9. 21:23
반응형


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된 상태에서
실질적인 메모리로의 반영이 되지 않는 경우가
있습니다.
단일 쓰레드의 프로그램이라면 별 상관 없겠지만,
다중쓰레드 프로그램일때, 여러 쓰레드가 한 변수에
접근한다면,
문제가 발생 할 수 있겠죠.

*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