我是否需要锁定并发方法,将ReadOnlyCollection作为参数?

时间:2014-11-07 20:20:30

标签: c# multithreading concurrency immutability

说一个方法看起来像这样。

Class MyClass
public string ConcatenateList(ReadOnlyCollection<string> aList)
{
  var result = new StringBuilder();
  foreach (string s in aList)
  {
     result.Append(", " + s);
  }
  return result.ToString();
} 

这是调用者将只读列表传递给MyClass.ConcatenateList方法的示例。

var list = new List<string>(){"hello","world"};
var readOnlyList = new ReadOnlyCollection<string>(list);

虽然该方法确实无法修改列表,但在执行方法时,调用者必须能够修改基础列表。此外,方法必须是并发

2个问题:

(1)鉴于上述要求,方法中是否存在竞争条件?据我所见,没有。 ThreadA永远不会读取或写入ThreadB的StringBuilder,因此没有并发问题,因此不需要锁定。真?

(2)是否会出现并发可能导致返回的字符串出现意外结果的情况?一个例子:ThreadA以&#34;,hello,world,howdy&#34;返回即使在&#34;你好&#34;在执行过程中添加到ThreadB所拥有的列表中。这会发生吗?

我试图理解,鉴于并发性,如果ConcatenateList()必须是&#34;纯函数&#34;即该方法保证其参数&#34; aList&#34;在整个方法执行期间永远不会被修改(由它自己或调用者)?

提前感谢您的想法!

1 个答案:

答案 0 :(得分:3)

ReadOnlyCollection不会将构造函数中提供的列表中的数据复制到仅显示只读成员的新集合中。相反,它只包装提供的IList,只暴露它的只读成员。

这意味着ReadOnlyList正在访问代码中原始List引用访问的相同内存,并且需要使用正确的同步才能使其安全。在此示例中,由于没有同步,调用者对基础列表的修改,而另一个线程正在访问只读列表,可能会导致任意数量的未定义行为。