如何锁定静态集合

时间:2017-03-10 13:20:51

标签: c# multithreading locking

使用lock关键字来实现区域应该最多在线程上执行,在多线程环境中,线程的其余部分将等待该区域。

我有一个集合IList<Student> student=new List<Student>(),正在多个类中使用。

在某些地方,对象会被添加到列表中,而在某些地方,对象会被删除。这会导致一些不一致的行为。

当我在多线程环境中锁定类x中的集合时,是否会锁定所有类的集合,并且不同类中的所有线程都将等待锁定?

Class StaticClass
{
 Public static IList<Student> student=new List<Student>();
} 


Class ClassA
{
 //add an item in the collection
} 

Class ClassB 
{
 //delete an item in the collection
} 

Class ClassC
{
//lock the collection here 

        lock (StaticClass.student)
        {

          foreach (ConnectionManager con in ConnectionManager.GetAllStudents())
          {
            con.Send(offlinePresence);
          }
        }

}

当我将集合锁定在ClassC中时,classA和ClassB的其他线程是否会等待?在for循环执行之前,允许nobody添加或删除集合中的项目,因为集合已被锁定?

2 个答案:

答案 0 :(得分:0)

System.Collections.Generic.SynchronizedCollection<T>程序集中查看System.ServiceModel.dll。所有的锁定内容都是内置的。

正如Fabio所说,ConcurrentBag也可以工作,但是每个访问它的线程都会创建一个单独的列表上下文。当您尝试删除项目时,它就像一个队列。一旦你的线程列表中的项目用完了,它就会从其他线程列表中“窃取”项目(以线程安全的方式)。

对于你的任务,我猜测SynchronizedCollection会更好。

答案 1 :(得分:0)

当您的代码获取对象的锁定时,它不会阻止从其他线程访问该对象。该对象发生的唯一事情是,只要没有释放锁,其他线程就无法获取对同一对象的锁定。

通常的做法是保留一个单独的普通对象作为锁的目标。

在您的示例中,只要代码没有先显式锁定它,其他线程仍然可以访问List<Student>对象。

锁定可能会导致严重的性能问题(线程等待彼此)并且在许多情况下不需要显式实现。只需看看.NET Framework的Concurrent集合类。