Search code examples
androidandroid-roomandroidxsynchronized

Why is a Room database initialisation synchronized?


While initialising the database using an abstract class in Rooms, the instance creation is generally done using synchronized. Why is this?

return INSTANCE ?: synchronized(this) {
     val instance = Room.databaseBuilder(
     context.applicationContext,
     DatabaseClass::class.java,
          "database_name",
      )
     .fallbackToDestructiveMigration()
     .build()

Solution

  • This is to control different threads accessing the database at once, to prevent multiple instances being created. If you didn't synchronise here, then two different threads could both create a new instance of the database, whereas the singleton pattern is supposed to facilitate a single shared instance across the lifecycle of your program.

    However the example you've linked in your question generally isn't enough and you should use something like double-check locking. So this might be better:

    return INSTANCE ?: synchronized(this) {
    
        INSTANCE ?: buildDatabase().also {
    
            INSTANCE = it
        }
    }
    

    As a side note, this isn't necessary. You could have no synchronisation and no shared instances. However it is recommended for the database to be a singleton due to expensive initialisation cost, so this is one example of a pattern to use.