Why is a Room database initialisation synchronized?

Viewed 628

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()
1 Answers

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.

Related