이 글은 http://www.androiddesignpatterns.com에 소개된 글을 저자의 동의를 얻고 번역한 것임을 알려드립니다.

원문 : http://www.androiddesignpatterns.com/2012/10/sqlite-contentprovider-thread-safety.html

 

ContentProvider를 사용할 때 가장 햇갈리는 부분은 thread-safety다.

작업이 오래 걸릴 수 있는 query에 대해 asynchronous(background)하게 처리해서 UI thread를 방해(block)하지 말아야 된다는 사실은 알고 있다. 그렇다면 multiple thread에서 ContentProvider에 접근해서 사용해도 괜찮은 건가?

 

Threads and Content Providers

ContentProvider에 대한 문서를 참고하면 method가 multiple thread에서 호출 될 수 있기 때문에, 반드시 thread-safe하게 처리되야 한다고 주의하고 있다.

Data access methods (such as insert(Uri, ContentValues) and update(Uri, ContentValues, String, String[])) may be called from many threads at once, and must be thread-safe.

다른 말로, “Android는 ContentProvider로의 접근을 동기화 해주지 않는다”는 말이고, 만약 서로 다른 thread에서 동일한 method를 동시에 요청하면 둘 중 하나는 반드시 대기해야 한다.

ContentProvider를 사용하려면 Framework 개발자의 입장에서 이러한 동시성(Concurrency) 문제를 직접 처리해줘야 한다.

 

Ensuring Thread Safety

이제 ContentProvider가 thread safe하지 않다는 사실을 알았다. 그럼 잠재적으로 발생할 수 있는 race condition을 어떻게 제거할 수 있나? 그냥 모든 method에 synchronized 접근자를 추가하면 되나?

ContentProvider가 데이터를 저장하기 위해 SQLiteDatabase를 사용한다는 사실을 감안하면 그럴 필요까지는 없을 것 같다. SQLiteDatabase 문서를 참고하면, SQLiteDatabase는 기본적으로 동기화됐기 때문에 2개의 thread가 동시에 접근할 수 없다. 따라서 각각의 ContentProvider method 사용에 synchronize 접근자를 사용하여 동기화하는 것은 불필요하다.

 

Conclusion

ContentProvider는 thread-safe를 보장하지 않지만,  race condition을 보장하기 위해 추가 구현은 불필요하다는 사실을 종종 볼 수 있다.

ContentProvider가 SQLiteDatabase를 기반으로 하고 있다는 사실을 감안하면, 2개의 thread가 동시에 data를 추가(write)하려고 시도하면 SQLiteDatabase는 먼저 들어온 하나의 thread가 작업을 완전히 종료할때까지 다른 하나의 thread를 대기 시킨다. 따라서 각각의 thread는 상호 배제적(mutually exclusive)으로 데이터에 접근할 수 있고, thread safe하다는 사실을 보장 받는다.

 

즉, ContentProvider는 thread safe를 보장하지 않지만, ContentProvider가 데이터를 저장하기 위해 사용하는 SQLiteDatabase는 thread safe를 보장하기 때문에 ContentProvider의 각각의 method에 synchronized 접근자를 추가하는 것은 불필요 할 때가 많다.