为什么在返回之前将volatile分配给局部变量
在查看 android LiveData 的实现时,我偶然发现了以下代码片段
public T getValue() {
Object data = mData;
if (data != NOT_SET) {
return (T) data;
}
return null;
}
为什么要在返回之前将类成员分配给局部变量?我的猜测是它关系到一个事实,即mData是volatile,但我不能完全理解我们为什么不能只return mData。
回答
我们想要 return mData,除非它等于NOT_SET因为然后我们想要 return null。想象一下,如果它天真地写成这样:
public T getValue() {
if (mData != NOT_SET) {
return (T) mData;
}
return null;
}
问题是根本没有同步,所以通过读取mData两次,我们创建了一个竞争条件。如果发生以下一系列事件怎么办?
mData包含一些不是的值NOT_SET,所以mData != NOT_SET通过,我们进入if块。- 另一个线程出现并设置
mData = NOT_SET;。 - 现在在
if块内的第一个线程返回(T) mData,即NOT_SET。但是null在这种情况下调用者预期!
事实上,这可能发生与否mData是volatile。该volatile关键字只是使它更容易。