使用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添加或删除集合中的项目,因为集合已被锁定?
答案 0 :(得分:0)
从System.Collections.Generic.SynchronizedCollection<T>
程序集中查看System.ServiceModel.dll
。所有的锁定内容都是内置的。
正如Fabio所说,ConcurrentBag也可以工作,但是每个访问它的线程都会创建一个单独的列表上下文。当您尝试删除项目时,它就像一个队列。一旦你的线程列表中的项目用完了,它就会从其他线程列表中“窃取”项目(以线程安全的方式)。
对于你的任务,我猜测SynchronizedCollection会更好。
答案 1 :(得分:0)
当您的代码获取对象的锁定时,它不会阻止从其他线程访问该对象。该对象发生的唯一事情是,只要没有释放锁,其他线程就无法获取对同一对象的锁定。
通常的做法是保留一个单独的普通对象作为锁的目标。
在您的示例中,只要代码没有先显式锁定它,其他线程仍然可以访问List<Student>
对象。
锁定可能会导致严重的性能问题(线程等待彼此)并且在许多情况下不需要显式实现。只需看看.NET Framework的Concurrent
集合类。