While looking at the implementation of android LiveData, I stumbled on the following code snippet
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
Why would one assign a class member to a local variable before returning it? My guess is it is related to the fact that mData
is volatile
, but I can't fully understand why couldn't we just return mData
.
We want to return mData
, except if it's equal to NOT_SET
because then we want to return null
. Imagine if it were naively written like this:
public T getValue() {
if (mData != NOT_SET) {
return (T) mData;
}
return null;
}
The problem is that there is no synchronization at all, so by reading mData
twice, we create a race condition. What if the following sequence of events happens?
mData
contains some value that's not NOT_SET
, so mData != NOT_SET
passes and we enter the if
block.mData = NOT_SET;
.if
block, returns (T) mData
, which is NOT_SET
. But the caller expected null
in this case!In fact this can happen whether or not mData
is volatile
. The volatile
keyword just makes it more likely.