일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 1일1커밋
- 캐치마인드
- 어떻게 나답게 살 것인가
- 끝말잇기
- 면접
- 좌식테이블
- 안드로이드
- 소프시스
- 소프시스 밤부 좌식 엑슬 테이블
- T자형인재
- 목적중심리더십
- 함수형 프로그래밍
- 북한살둘레길
- 베드트레이
- 아비투스
- 한단어의힘
- 한달어스
- 한달독서
- 베드테이블
- 브런치작가되기
- 슬기로운 온라인 게임
- 목적 중심 리더십
- 지지않는다는말
- 리얼하다
- 프래그먼트
- 자취필수템
- 재택근무
- 커스텀린트
- 한달브런치북만들기
- 테트리스
- Today
- Total
정상에서 IT를 외치다
싱글톤이란? (feat. JAVA, Kotlin) 본문
싱글톤은 소프트웨어 디자인 패턴 중의 하나로 오직 하나의 인스턴스만을 가진다.
Singleton Pattern - Wiki
여기서 인스턴스는 OOP의 관점에서 객체가 메모리에 할당되어 실제 사용될 때를 가리킨다. 위키피디아에 따르면 싱글톤은 다음 5가지 방식으로 문제를 해결한다.
1. 클래스에 인스턴스가 하나만 있는지 확인
2. 클래스의 유일한 인스턴스에 쉽게 접근
3. 인스턴스화 제어
4. 인스턴스 수 제한
5. 전역 변수 접근
이렇게 함으로써 생성자를 숨길 수 있고 static 함수를 사용해 클래스에서 오직 1개의 인스턴스만을 반환할 수 있다. 근데 여기서 문제가 발생할 수 있다. 바로 멀티쓰레드에서 말이다.
멀티쓰레드에서의 문제
멀티쓰레드 환경에서 동시에 클래스에 접근하게 되면 문제가 발생할 수 있다. 싱글톤이지만 객체를 여러개 생성될 수 있다. 이를 위해 Lazy Loaded SingleTon (늦은 초기화) 와 Double-checked locking (DCL) 방식으로 이를 방지할 수 있다.
Lazy Loaded SingleTon - Wiki
public class Something {
private Something() {}
private static class LazyHolder {
static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
위는 위키에 있는 예제이다. 여기서 중요한 것은 static class를 맴버 변수로 선언했다는 거다. 그렇게 되면 어떤 일이 일어날까? 위키의 내용 일부를 읽어보자.
The static class LazyHolder is only executed when the static method getInstance is invoked on the class Something, and the first time this happens the JVM will load and initialize the LazyHolder class.
static class 맴버 변수는 getInstance 될때 오직 1개만 JVM에서 생성해 준다는 것이다. JVM 스펙이므로 우리는 1개의 인스턴스만이 생성되고 사용되어 진다고 믿고 쓸수 있다.
참고로 아래는 필자가 생각하는 위와 근접한 코틀린 코드 이다.
참고 - stackoverflow
class Something private constructor(){
companion object {
val instance: Something by lazy(LazyThreadSafetyMode.PUBLICATION) { Something() }
}
}
Double-checked locking - Wiki
class Something private constructor(){
companion object {
private var instance: Something? = null
fun getInstance() =
instance ?: synchronized(this) {
instance ?: Something().also { instance = it }
}
}
}
인스턴스를 가져올 때 null 인지 확인힙니다. 또한 synchronized 블록에서도 한번 더 null 체크 후 값을 반환합니다. 이렇게 함으로써 멀티쓰레드 환경에서도 1개의 instance만 생성하여 사용할 수 있도록 합니다.
@Volatile
@Volatile private var instance: Something? = null
voltile 키워드는 Java 변수를 Mina Memory에 저장하겠다는 것을 명시하는 것입니다. 매번 변수의 값을 Read/Write 할 때마다 CPU cache에 저장된 값이 아닌 Main Memory에서 가져와서 사용합니다.