首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在C#中,为线程安全使用Queue.Synchronized或lock()会更好吗?

在C#中,为线程安全使用Queue.Synchronized或lock()会更好吗?
EN

Stack Overflow用户
提问于 2008-12-03 21:13:34
回答 4查看 58.1K关注 0票数 62

我有一个队列对象,我需要确保线程安全。是否最好使用这样的锁对象:

代码语言:javascript
复制
lock(myLockObject)
{
//do stuff with the queue
}

还是建议像这样使用Queue.Synchronized:

代码语言:javascript
复制
Queue.Synchronized(myQueue).whatever_i_want_to_do();

在读取MSDN文档时,它说我应该使用Queue.Synchronized使其线程安全,但随后给出了一个使用lock对象的示例。来自MSDN的文章:

为了保证队列的线程安全,所有操作必须仅通过此包装器完成。

枚举集合本质上不是一个线程安全的过程。即使在同步集合时,其他线程仍然可以修改集合,这将导致枚举数抛出异常。要确保枚举期间的线程安全,可以在整个枚举期间锁定集合,或者捕获其他线程所做更改导致的异常。

如果调用同步()不能确保线程安全,那么它有什么意义呢?我是不是漏掉了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-12-03 21:25:12

就我个人而言,我总是更喜欢上锁。这意味着你可以决定粒度。如果您只依赖于同步包装器,那么每个单独的操作都是同步的,但是如果您需要做不止一件事情(例如,迭代整个集合),那么无论如何您都需要锁定。为了简单起见,我只想记住一件事--适当地锁定!

编辑:正如注释中所指出的,如果您可以使用更高级别的抽象,那就太好了。如果您确实使用了锁定,那么要小心--记录您期望锁定在何处的内容,并尽可能短地获取/释放锁(更多的是为了正确性而不是性能)。在持有锁时避免调用未知代码,避免嵌套锁等。

在.NET 4中,支持更高级别的抽象(包括无锁代码)。不管怎样,我还是不建议使用同步包装器。

票数 50
EN

Stack Overflow用户

发布于 2008-12-03 21:49:54

旧集合库中的Synchronized方法存在一个主要问题,因为它们在粒度太低的情况下同步(每种方法而不是每个工作单元)。

有一个典型的同步队列的争用条件,如下所示,您将检查Count以查看去队列是否安全,但是Dequeue方法会抛出一个指示队列为空的异常。这是因为每个单独的操作都是线程安全的,但是Count的值可以在查询它时和使用该值时进行更改。

代码语言:javascript
复制
object item;
if (queue.Count > 0)
{
    // at this point another thread dequeues the last item, and then
    // the next line will throw an InvalidOperationException...
    item = queue.Dequeue();
}

您可以使用手动锁安全地编写整个工作单元(即检查计数并将项目排除队列)如下:

代码语言:javascript
复制
object item;
lock (queue)
{
    if (queue.Count > 0)
    {
        item = queue.Dequeue();
    }
}

因此,由于您无法从同步队列中安全地排出任何队列,所以我不会去理会它,而只会使用手动锁定。

.NET 4.0应该有大量正确实现的线程安全集合,但不幸的是,这还需要将近一年的时间。

票数 35
EN

Stack Overflow用户

发布于 2008-12-03 22:29:24

这样,我们就不需要锁定队列就可以发现队列是空的。

代码语言:javascript
复制
object item;
if (queue.Count > 0)
{
  lock (queue)
  {
    if (queue.Count > 0)
    {
       item = queue.Dequeue();
    }
  }
}
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/338712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档