我有一个类,代码如下
private readonly object m_lock = new object();
private IClient m_client
private object m_context;
在设置client和context的时候,我是这样加锁的
lock(m_lock)
{
m_client = theClientFromSomewhere;
m_context = contextObject;
}
我的问题是,如果我只需要自己获取m_client
,这样做安全吗?
var localClient = m_client;
Debug.Assert(localClient != null);
localClient.DoStuff();
m_client
是引用类型,因此读取(分配给 localClient
时)is guaranteed to be atomic ,所以这应该可以在单个 CPU 上正常工作。
我可以(在理论上)使 m_client
变量成为 volatile
,然后通过防止其他 CPU 的乱序读取,这在多个 cpu 上是安全的,但问题是,写入时锁定是否可以在不发生 volatile 的情况下安全读取?
写入时锁定是否会“刷新”CPU 缓存,以便在读取时不会发生乱序?
最佳答案
C# 中的
lock
(通常,它在 .NET 中扩展到的 Monitor
)是一个内存屏障 - 具体来说,获取时的读取屏障、写入屏障发布时。至于volatile
,它为每次对该字段的读写添加了一道屏障。所以,是的,使用 volatile
应该是安全的(假设您没有显示的其余代码正在正确执行所有操作)。
关于c# - 如果我在写入变量时锁定,如果读取是原子的,我是否也需要在读取时锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1169562/