我正在 C# 中构建一个多线程缓存,它将保存 Car 对象的列表:
public static IList<Car> Cars {get; private set;}
我想知道在不锁定的情况下更改线程中的引用是否安全?
e.g.
private static void Loop()
{
while (true)
{
Cars = GetFreshListFromServer();
Thread.Sleep(SomeInterval);
}
}
基本上,我猜这取决于为 Cars 分配新的引用是否是原子的。
如果不是,我显然必须为我的汽车使用私人领域,并锁定获取和设置。
是的,参考更新在语言规范中保证是原子的。
5.5 变量引用的原子性
以下数据类型的读取和写入是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。此外,对具有前面列表中的基础类型的枚举类型的读取和写入也是原子的。其他类型(包括 long、ulong、double 和decimal)以及用户定义类型的读取和写入不保证是原子的。
然而在一个紧密的循环中你might被寄存器缓存所困扰。在这种情况下不太可能,除非您的方法调用是内联的(这可能会发生)。我个人会添加lock
使其变得简单且可预测,但是volatile
也可以在这里提供帮助。请注意,完整的线程安全不仅仅是原子性。
在缓存的情况下,我会查看Interlocked.CompareExchange
,个人 - 即try更新,但如果失败重做工作从头开始(从新值开始)并重试。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)