在实现线程安全队列或列表时,是否需要在返回Count之前锁定?

Jal*_*aid 4 c# multithreading locking thread-safety

实现线程安全列表或队列时; 是否需要List.Count在返回Count之前锁定属性,即:

//...
public int Count 
{
    lock (_syncObject)
    {
       return _list.Count;
    }
}
//...
Run Code Online (Sandbox Code Playgroud)

是否有必要进行锁定,因为原始_list.Count变量可能不是易变量?

Hen*_*man 5

是的,这是必要的,但大多是无关紧要的.如果没有锁定,您可能会读取陈旧的值,甚至根据内部工作和_list.Count的类型,引入错误.

但请注意,使用该Count属性是有问题的,任何调用代码都不能真正依赖它:

if (myStore.Count > 0)  // this Count's getter  locks internally 
{
    var item = myStore.Dequeue(); // not safe, myStore could be empty
}
Run Code Online (Sandbox Code Playgroud)

因此,您应该设计一个设计,其中检查计数并对其进行组合:

ItemType GetNullOrFirst()
{
    lock (_syncObject)
    {
       if (_list.Count > 0)
       {
           ....
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

额外:

因为原始的_list.Count变量可能不是一个volatile变量,所以锁定是否必要?

_list.Count不是一个变量,但属性.它不能标记为易变.它是否是线程安全的取决于属性的getter代码,但它通常是安全的.但不可靠.