Skip to content

배토의 개발일지

나를위한 단편적 기억들의 기록

Menu
  • 안드로이드
  • 코틀린
  • Godot
  • 블렌더
  • git
  • 게임제작일지
  • 기타
Menu

Multithread Singleton 구현에서의 Double-checked locking pattern

Posted on 2021년 7월 16일 by batmask

안드로이드 Room에서 Database 클래스의 Singleton 구현에 조금 의아해 보이는 코드가 있었다. Database class 코드를 다시보면 아래와 같은데,

@Database(entities = [Car::class, Ticket::class], version = 1)
abstract class ParkingDatabase : RoomDatabase(){
    abstract fun carDao(): CarDao
    abstract fun ticketDao(): TicketDao

    companion object {
        // For Singleton instantiation
        @Volatile private var instance: ParkingDatabase? = null

        fun getInstance(context: Context): ParkingDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): ParkingDatabase{
            return Room.databaseBuilder(context.applicationContext, ParkingDatabase::class.java, "Parking").build()
        }
    }
}

singleton 구현부분에서 getInstance() 함수만 떼어서 보자.

...
fun getInstance(context: Context): ParkingDatabase {
    return instance ?: synchronized(this) {
        instance ?: buildDatabase(context).also { instance = it }
    }
}
...

코드를 보면, instance의 null 여부를 두 번 체크하고 있다. 생각없이 보면 이상할 수 있는데, 멀티 쓰레드 동기화시 꼭 필요한 부분이며 Double-checked locking 이라고 부르는 디자인 패턴이다. 링크의 위키페이지를 따라가면 관련 설명이 있다.

이렇게 두번 체크하는 이유를 살펴보자. 첫번째 instance의 null체크는 synchronized로 lock을 거는 부하를 줄이기 위함이다. 값이 존재하면 lock 오브젝트를 생성할 필요가 없으니까.
체크를 했는데, synchronized 블럭에 진입해서 한번 더 instance의 null을 체크하는 이유는 다음과 같다. synchronized 블럭에 진입전에 lock이 걸려있으면 풀릴때까지 대기를 하게되고, 그사이 lock을 잡고있는 다른 쓰레드에서 instance를 생성했을 가능성이 있기 때문이다.(위 코드에선 가능성이 아니라 생성했겠지.) 대기가 풀리고 synchronized 블럭에 진입했을 때, 이와같은 상황에서 중복생성을 막기 위함이다.

아주 간단하지만, 보통 구현시 첫번째 체크없이 바로 synchronized 블럭만 돌리는 경우도 많고, 멀티쓰레드 상황을 의식하지 않으면 더블체크가 이상하게 보일 수도 있다. 하지만, 알고나면 이게 최적의 코드라는 것. 그러니까 디자인 패턴이겠지.

답글 남기기 응답 취소

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

최신 글

  • Blender : snap을 써서 다른 vertex에 정렬하기
  • KTor Client 기본 사용 정리
  • 게임 만들거다.
  • Using Koin with Android Compose

보관함

2021 7월
일 월 화 수 목 금 토
 123
45678910
11121314151617
18192021222324
25262728293031
« 6월   8월 »

메타

  • 로그인
  • 엔트리 피드
  • 댓글 피드
  • WordPress.org
©2025 배토의 개발일지 | Built using WordPress and Responsive Blogily theme by Superb