Thursday, October 11, 2012

SQLite, ContentProviders, and Thread Safety

A common source of confusion when implementing ContentProviders is that of thread-safety. We all know that any potentially expensive query should be asynchronous so as not to block the UI thread, but when, if ever, is it OK to make calls to the ContentProvider from multiple threads?

Threads and ContentProviders

The documentation on ContentProviders warns that its methods may be called from multiple threads and therefore must be 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.

In other words, Android does not synchronize access to the ContentProvider for you. If two calls to the same method are made simultaneously from separate threads, neither call will wait for the other. Requiring the client to deal with concurrency themselves makes sense from a framework developer's point of view. The abstract ContentProvider class cannot assume that its subclasses will require synchronization, as doing so would be horribly inefficient.

Ensuring Thread Safety

So now that we know that the ContentProvider is not thread safe, what do we need to do in order to eliminate potential race conditions? Just make every method synchronized, right?