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()
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.