c# - 实现线程安全的队列或列表时,返回Count前是否需要加锁?

标签 c# multithreading locking thread-safety

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

//...
public int Count 
{
    lock (_syncObject)
    {
       return _list.Count;
    }
}
//...

是否因为原来的_list.Count变量可能不是volatile变量,所以需要加锁?

最佳答案

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

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

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

因此,您的目标应该是一种将检查计数和对其执行操作相结合的设计:

ItemType GetNullOrFirst()
{
    lock (_syncObject)
    {
       if (_list.Count > 0)
       {
           ....
       }
    }
}

附加:

is it nessesary to do a lock because of the original _list.Count variable maybe not a volatile variable?

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

关于c# - 实现线程安全的队列或列表时,返回Count前是否需要加锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4047224/

相关文章:

java - JProgressBar 不更新,找不到线索

java - LinkedBlockingQueue 上的 add() 是否通知等待线程?

c# - C++ dll 返回的字符串在 C# 调用程序中已损坏,为什么?

c# - 如何强制所有派生类实现抽象方法或属性?

c# - 在没有 Visual Studio 的情况下使用 Microsoft.VisualStudio.TestTools.UnitTesting?

c# - 无法从下拉列表中选择元素

java - 使用 Future 与 CompletableFuture 的 invokeall()

java - 当线程条件为 true 时,内部是否可以进行时间检查

java - 如何获得对某些 session 条目的独占访问权?

multithreading - 不变的数据和锁定