Android Thread-Safe singleton

윤예은·2022년 9월 6일

서론

개인 토이 프로젝트를 할 때에 싱글톤을 자주 활용했었다. 하지만 내가 사용하고 많은 인터넷 예제들이 사용하던 싱글톤을 만드는 방법이 Multi Thread 환경에서 위험하다는 것은 아주 유명한 이야기이다.

토이 프로젝트를 할 때에는 어차피 모든 싱글톤 객체를 UI Thread 위에서 만들고 있었다. 따라서 사실상 Thread 관리를 해야한다는 필요성을 느끼지 못했다. 그러나 당시에도 테스트를 진행해 볼 때 싱글턴 객체가 하나가 아닌 적이 발생하여 불편함이 있었고.. 이번 기회에 조사해보기로 마음먹었다.

방법 0

아무 대책 없음

constructor가 private인 클래스에서 static 변수로 된 단 하나의 인스턴스를 getInstance()를 사용하여 받아오는 방법이다.
최초부터 static 변수에 인스턴스를 만들어두고 사용하는 상대적으로 안전한 방법이 있지만, 그렇게 하면 사용하지 않더라도 메모리가 할당된다는 단점이 있다고 한다.

방법 1

Double Checked Locking

synchronized를 사용하면 멀티스레드에서도 같은 객체를 가져올 것을 보장할 수 있지만, 원리상 여러 개의 스레드들이 줄을 서서 다른 스레드가 해당 함수를 다 돌고 나가기를 기다려야 하는 단점이 있다고 한다. 따라서 함수 자체를 synchronized로 설정하기보다, null체크를 한번하고 그 후에 synchronized로 한번 더 체크한 후 반환하는 것으로 개선한 것이다.
이때에 Voletile이라는 것에 대해 배웠는데, cpu 캐시에 생기는 임시 데이터를 생성하지 않아서 속도는 조금 느리지만 같은 변수일 것을 더욱 보장할 수 있는 기능이라고 한다.

방법 2

Enum

Joshua Bloch가 언급한 이디엄으로, 클래스 대신 enum으로 정의하는 것이다. 그러나 안드로이드에서는 context라는 의존성이 필요한 경우가 많기 때문에 많은 상황에서의 사용에 제한이 걸릴 가능성이 높다고 한다.

방법 3

LazyHolder

별개의 static class와 그 안의 static 변수로 인스턴스를 가지고 있어서, getInstance()를 불렀을 때가 되어서야 static 변수에 인스턴스가 생기면서 단 하나를 보장할 수 있는 방법이라고 한다.

방법 4

(Kotlin)Object

단 하나의 인스턴스만 필요한 경우 클래스를 만들지 말고 바로 인스턴스를 만들어서 사용하는 방법이다. 그러나 클래스로더가 여러 개 있을 경우에는 클래스가 여러번 로드되면서 싱글톤이 아니게 될 수도 있다고 한다.

방법 5

(Hilt)Singleton

Dagger의 singleton이 안전하듯이 hilt를 사용하여 싱글턴 객체를 관리한다면, Thread에서 안전할 것을 보장할 수 있다고 한다.

주의!! 같은 DI 라이브러리인 Koin의 경우에는 Thread-safe 하지 않다는 이야기도 보였음!

결론

만약에 Hilt를 적용한다면 문제 없을 것이고, Hilt를 적용하지 않는다면, LazyHolder 패턴을 사용하여 만들면 좋을 것 같다.

참고

https://jainilgada.medium.com/thread-safe-singleton-pattern-b429e79825d2
https://rockdrumy.tistory.com/1412
https://stackoverflow.com/questions/30179793/are-kotlins-singletons-thread-safe
https://stackoverflow.com/questions/56825097/synchronized-singleton-in-kotlin
https://kotlinlang.org/docs/object-declarations.html
https://stackoverflow.com/questions/30240338/is-singleton-in-dagger-2-thread-safe
https://developer.android.com/training/dependency-injection/manual?hl=ko
https://injae-kim.github.io/dev/2020/08/06/singleton-pattern-usage.html
https://sogno-ing.tistory.com/102
https://coding-start.tistory.com/203

profile
안녕하세요!!

0개의 댓글