【问题标题】:Locking individual elements in a static collection?锁定静态集合中的单个元素?
【发布时间】:2011-02-28 23:16:17
【问题描述】:

我有一个静态的对象集合,这些对象会经常从多个线程中更新。是否可以锁定集合中的单个对象而不是锁定整个集合,这样只有尝试访问集合中相同对象的线程才会被阻塞,而不是每个线程都会被阻塞?

如果有更好的方法从多个线程更新集合中的对象,我会全力以赴。

【问题讨论】:

标签: .net asp.net multithreading


【解决方案1】:

参考Data Structures for Parallel Programming on MSDN,这些比用户锁定机制快得多。

System.Collections.Concurrent 命名空间中的集合类提供线程安全的添加和删除操作,尽可能避免锁定,并在需要锁定时使用细粒度锁定。

与 .NET Framework 1.0 和 2.0 版中引入的集合不同,并发集合类在访问项目时不需要用户代码获取任何锁。

【讨论】:

  • 我一直在寻找可以充当一次一个的阻塞连接池的东西,而您的链接正是我所需要的:BlockingCollection 默认情况下是一个包​​装器并发队列.
【解决方案2】:

首先,在 ASP.NET 应用程序中,最好使用 HttpCache 对象,而不是简单的静态集合。

关于您的实际问题,您确实可以为集合中的每个项目维护一个锁(每个对象在 .NET 中都有一个监视器,因此它们相对便宜)。但是,您可能希望在锁定实际集合的同时执行此操作:

为了简单起见,我将在这里使用静态,但正如我上面提到的,HttpCache 可能会更好:

class CacheItem
{
    private readonly object _lock = new object();

    public void DoSomething()
    {
       lock(_lock)
       {
           // perform some synchronized action on the individual item  
       }
    }
}

// I'd recommend a reader-writer lock for the
// collection so that you can have multiple retrievals
// of items and still lock exclusively for changing the collection
private static ReaderWriterLockSlim itemsLock = new ReaderWriterLockSlim();
private static List<CacheItem> items = new List<CacheItem>();

public static void AddItem(CacheItem item)
{
    itemsLock.EnterWriteLock();

    try
    {
       items.Add(item);
    }
    finally
    {
        itemsLock.ExitWriteLock();
    }
}

pulbic static CacheItem GetItem(int index)
{
    itemsLock.EnterReadLock();

    try
    {
        return items[index];
    }
    finally
    {
        itemsLock.ExitReadLock();
    }
}

【讨论】:

    【解决方案3】:

    首先,你永远不会锁定一个对象,它是你锁定的代码。锁不会以任何方式保护数据,它只会阻止其他线程输入相同的代码。

    一个对象被用作一个锁的标识符,这样你可以使用相同的标识符来锁定多个方法,或者使用不同的标识符来锁定同一个方法。

    要在方法处理特定数据时将锁应用于方法,您只需要一个对该数据唯一的标识符。如果数据是一个对象,你可以简单地使用对象本身作为标识符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多