Skip to content

Singleton database creation is not thread-safe #179

@rhashimoto

Description

@rhashimoto

URL of codelab:
https://developer.android.com/codelabs/basic-android-kotlin-compose-persisting-data-room#0

In which task and step of the codelab can this issue be found?
Task 7 (Create a Database instance), step 20. The text says:

Multiple threads can potentially ask for a database instance at the same time, which results in two databases instead of one. This issue is known as a race condition. Wrapping the code to get the database inside a synchronized block means that only one thread of execution at a time can enter this block of code, which makes sure the database only gets initialized once. Use synchronized{} block to avoid the race condition.

Describe the problem
As written, InventoryDatabase.getDatabase() is actually not thread-safe. There is a race condition if another thread sets Instance after the test but before the current thread acquires the lock.

The proper pattern is double-checked locking which requires another test of the condition inside the synchronized block.

fun getDatabase(context: Context): InventoryDatabase {
// if the Instance is not null, return it, otherwise create a new database instance.
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, InventoryDatabase::class.java, "item_database")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions