锁定iList.net线程安全

锁定iList.net线程安全,.net,multithreading,thread-safety,locking,.net,Multithreading,Thread Safety,Locking,我只是不明白为什么添加到列表中不会像下面这样是线程安全的 object aLock = new object(); List<string> aList = new List<string> lock(aLock) aList.Add("abc"); object aLock=new object(); 列表列表=新列表 锁(阿洛克) 添加(“abc”); 不确定为什么在您所做的只是添加锁的地方需要锁。 为什么这样的场景不是线程安全的?示例代码是无用的——正如

我只是不明白为什么添加到列表中不会像下面这样是线程安全的

object aLock = new object();
List<string> aList = new List<string>

lock(aLock)
   aList.Add("abc");
object aLock=new object();
列表列表=新列表
锁(阿洛克)
添加(“abc”);
不确定为什么在您所做的只是添加锁的地方需要锁。
为什么这样的场景不是线程安全的?

示例代码是无用的——正如@Jon提到的,所有线程都会锁定自己的对象,这意味着它们根本不会互相阻塞。不妨完全省略lock语句

首先,您需要锁定所有线程都通用的对象(如列表本身)。例如:

lock (aList)
    aList.Add("abc");
至于“为什么”,列表的内部实现可能(确实)执行在多个线程上并行执行不安全的操作。这记录在以下文件中:

此类型的公共静态(在Visual Basic中共享)成员是线程 安全的。任何实例成员都不能保证线程安全

列表可以同时支持多个读卡器,只要 集合未被修改。在集合中枚举是不正确的 本质上不是线程安全的过程。在罕见的情况下 枚举与一个或多个写访问争用,这是 确保线程安全是在整个过程中锁定集合 枚举。允许多个用户访问集合的步骤 对于读写线程,您必须实现自己的线程 同步


…如果两个线程同时添加…另外,从每个线程锁定不同的对象(例如,此处
aLock
是一个本地对象,因此运行此代码的两个线程将分别锁定不同的实例)是一种代价高昂的方法,完全不需要执行任何操作。小心!锁定列表本身也是一个bug,除非列表的可见性限制在已知范围内(例如,如果它是
私有
字段)。通常,对锁定目标的访问必须限制在已知的范围内——如果锁定目标是
公共的
,这是不可能的。对不起,我不明白您的解释Jon,如果列表是公共的,为什么锁定列表是个问题?因为您锁定的是属性的实例(内容),而不是属性本身。如果它是公共的,那么代码的任何其他部分都可能进入并更改内容,从而导致某些线程在对象上持有锁,而其他线程不再锁定该对象。