The android room with a view codelab (<https://cod...
# announcements
d
The android room with a view codelab (https://codelabs.developers.google.com/codelabs/android-room-with-a-view-kotlin/#7) gives you this code to copy-paste, but doesn't explain why they use the kotlin coroutines internal function
synchronize
, or how to understand how it works. Can anyone help me figure out what this actually does? (I figured out it was an internal fn from the warning I got from Android Studio)
Copy code
// Annotates class to be a Room Database with a table (entity) of the Word class
@Database(entities = arrayOf(Word::class), version = 1, exportSchema = false)
public abstract class WordRoomDatabase : RoomDatabase() {

   abstract fun wordDao(): WordDao

   companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time. 
        @Volatile
        private var INSTANCE: WordRoomDatabase? = null

        fun getDatabase(context: Context): WordRoomDatabase {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }
            synchronized(this) {
                val instance = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java, 
                        "word_database"
                    ).build()
                INSTANCE = instance
                return instance
            }
        }
   }
}
Is all this necessary? How does this differ from the more normal way I've seen people write something to cache a return value, which doesn't use
@Volatile
or
synchronized
? Something like
Copy code
private var _cache: WordRoomDatabase? = null

fun getDatabase(context: Context): WordRoomDatabase {
    val cached = _cache // also, why is this necessary actually?
    if (cached != null) {
        return cached
    } else {
        _cache = Room.databaseBuilder(
                        context.applicationContext,
                        WordRoomDatabase::class.java, 
                        "word_database"
                    ).build()
        return cache
    }
}
i
Note that it uses
synchronized
, not
synchronize
- those are different things
d
Thanks. I think I just mis-typed, and
synchronized
is the internal function I got warned about?
i
synchronized
is not an internal function (nor should you have any import related to
synchronized
- that would indicate you are using the wrong one)
The key part is to be safe to be called on multiple thread simultaneously. Your
_cache
version is not thread safe
d
If I use coroutines and not threads, under the hood do they use threads in a way that will make that unsafe?
i
I don't understand your question. Calling your
getDatabase()
from two different coroutines simultaneously is also not safe
unless you use some mechanism such as
synchronized
to ensure that only one caller can be inside that block at a time
p
the first implementation uses the ‘double-checked locking’ idiom, whereas the second is just not thread-safe.