在我的多线程asmx web服务中,我有一个我自己的类型SystemData的类字段_allData,它由几个List<T>
和Dictionary<T>
组成,标记为volatile
。系统数据(_allData
)稍后刷新一次,我通过创建另一个名为newData
的对象并使用新数据填充其数据结构。当它这样做我只是分配引用赋值是原子,所以为什么Interlocked.Exchange(ref Object,Object)需要?
private static volatile SystemData _allData
public static bool LoadAllSystemData()
{
SystemData newData = new SystemData();
/* fill newData with up-to-date data*/
...
_allData = newData.
}
这应该工作,因为任务是原子,并且具有参考旧数据线程继续使用它,只是分配后剩下的有新的系统数据。然而,我的同事说,而不是使用volatile
关键字和简单的assigment我应该使用InterLocked.Exchange
,因为他说,在某些平台上,不保证参考分配是原子。另外:当我宣布the _allData
字段volatile
的
Interlocked.Exchange<SystemData>(ref _allData, newData);
产生警告“的挥发性字段的引用将不会被视为挥发性”我应该怎么看待这个?
谢谢!最好的答案! – 2010-02-05 16:30:50
从我所听到的Interlocked.Exchange也保证了内存屏障的创建。因此,如果您例如创建一个新对象,然后分配一些属性,然后将对象存储在另一个引用中而不使用Interlocked.Exchange,那么编译器可能会扰乱这些操作的顺序,从而导致访问第二个引用而不是线程 - 安全。那真的是吗?是否有意义使用Interlocked.Exchange是那种场景? – Mike 2010-12-14 14:17:50
@Mike:当谈到低锁多线程情况下可能出现的情况时,我和下一个人一样无知。答案可能因处理器而异。你应该向专家提出你的问题,或者如果它对你感兴趣,请阅读这个主题。乔·达菲的书和他的博客是开始的好地方。我的规则:不要使用多线程。如果你必须使用不可变的数据结构。如果你不能,使用锁。只有当你*必须*具有无锁的可变数据时,才应该考虑低锁技术。 – 2010-12-14 15:05:14