2012-01-16 107 views
1

我只是困惑,为什么添加到列表中不会被线程安全的像下面锁ILIST .NET线程安全

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

lock(aLock) 
    aList.Add("abc"); 

不知道为什么会在那里你正在做的是增加了它需要一个锁。 为什么这样的场景不是线程安全的?

+5

......如果两个线程同时添加...... – 2012-01-16 02:01:57

+5

另外,从每个线程中锁定一个不同的对象(例如'aLock'是本地的,所以运行这个代码的两个线程会锁定一个每个不同的实例)是一种完全没有用的昂贵的方式。 – Jon 2012-01-16 02:05:31

回答

2

示例代码没用 - 正如@Jon提到的,所有线程都会锁定在自己的对象上,这意味着它们根本不会互相阻塞。也可能完全忽略锁定语句。

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

lock (aList) 
    aList.Add("abc"); 

至于“为什么”,内部实行名单的可能(没有)执行无法在安全上并行多线程执行操作。这是记录在List class MSDN docs

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

只要 集合未被修改,列表可以同时支持多个阅读器。枚举枚举通过 本质上不是一个线程安全的过程。在枚举枚举与一个或多个写入访问竞争的罕见情况下, 确保线程安全的唯一方法是在整个枚举过程中锁定集合。要允许通过多个 线程访问该集合以进行读写,您必须实现自己的 同步。

+1

**小心!**锁定列表本身也是一个错误,除非列表的可见性限制在已知范围内(例如,如果它是“私人”字段)。一般来说,访问锁定目标**必须被限制在一个已知的范围内 - 如果锁定目标是“public”,这是不可能的。 – Jon 2012-01-16 04:06:00

+0

是的,好点 – 2012-01-16 04:06:55

+0

对不起,我不理解你解释乔恩,为什么锁定列表上的问题,如果它是公开的? – TheWommies 2012-01-16 04:35:57