The first major difference is returned value.
First method will return and instance of FakeDatabase because of Elvis Operator. it will return instance if not null or create one and assign it to instance and return.
Second method is not returning anything You can check it by calling it . it will return an Unit because you only have an assignment statement here. You can make it work by adding returned value for synchronize block at last line .
fun getInstance() = instance ?: synchronized(this) {
instance = FakeDatabase()
instance!!
}
But this just for demonstration purpose you can concise is as follows. You do not need ?: inside again.
fun getInstance() = instance ?: synchronized(this) {
FakeDatabase().also { instance = it }
}
If you have doubt about also its just an Scoping function. It allows to perform operation on an object and its return the same Object. in this case a FakeDatabase object after assigning it to instance.