2014-09-05 69 views
0

当我有这样的代码:是List <T>(列表<T>)构造函数线程安全吗?

public static List<Module> ExtensionList 
{ 
    get 
    { 
     return new List<Module>(Extensions); 
    } 
} 

是线程安全的?例如。它是否在Extensions上发行锁定,并复制列表?或者我应该明确地做到这一点:

public static List<Module> ExtensionList 
{ 
    get 
    { 
     lock (Extensions) 
     { 
      return new List<Module>(Extensions); 
     } 
    } 
} 
+2

号根据MSDN,在'名单所有非静态成员'不guarraned是线程安全的:“公共静态(共享在Visual Basic中)这种类型的成员是线程安全的。任何实例成员不保证是线程安全的。“更多:http://msdn.microsoft.com/pl-pl/library/6sh2ey19(v=vs.110).aspx – 2014-09-05 07:41:21

+0

@pwas为什么这是一个不好的做法?你能详细说明吗?谢谢 – Petr 2014-09-05 07:51:45

回答

4

MSDN明确指出,没有List<T>方法是线程安全的:

所有实例成员不能保证线程安全的。

对List执行多个读取操作是安全的,但如果在读取集合时被修改,则会发生问题。

构造函数本身总是线程安全的:您不能从另一个实例调用它。

如果用其他List<T>提供您List<T>构造,就像你在你的代码做的,这是不是安全的,因为进入List<T>可能同时通过构造函数(然后上述规则适用)正在处理改变。

+0

我可以批准这一点。我只是反映了.NET代码,没有锁定语句,监视器或其他相关的东西。 – feO2x 2014-09-05 07:45:04

+1

但这是锅炉板文本,这里几乎不重要。这很难(不可能?)使用多线程的构造函数。问题是关于参数。 – 2014-09-05 07:46:03

+0

@HenkHolterman:答案正确吗?我清楚地指出,如果列表被用作传入参数,它是不安全的。如果调用无参数构造函数,它是安全的。 – 2014-09-05 07:46:31

1

即使您将构造函数设置为锁定语句,该列表的用法也不会是线程安全的。

使用一个线程安全的集合像BlockingCollection

http://msdn.microsoft.com/en-us/library/dd997305(v=vs.110).aspx

+0

编号线程安全的集合简化语法 - 我们不需要使用'lock'或任何方法来锁定。但正确使用'lock'可以为任何操作提供线程安全性。 – 2014-09-05 07:48:16

+0

Axdorph是正确的,第二个带'lock()'的样本本身并不能保证线程安全。正确性取决于访问扩展的其他代码。 – 2014-09-05 07:49:40

+0

@Ok - 对,外面的课也必须正确使用锁。 – 2014-09-05 07:51:09

相关问题